2011-07-05 13 views
90

因爲我對R相當陌生,所以我不知道S3方法和對象是什麼。我發現有S3和S4對象系統,並且有些人建議儘可能使用S4以上的S3(http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html)。但是,我不知道S3方法/對象的確切定義。R中的「S3方法」是什麼意思?

回答

65

大部分相關信息可以通過查看?S3?UseMethod找到,但簡而言之:

S3是指方法調度的方案。如果您已經使用R一段時間,您會注意到有很多不同類型的對象有printpredictsummary方法。

在S3中,這是通過:

  • 設置類的 利益(例如:一個 調用到方法的返回值glm具有類glm)對象的
  • 提供與方法一般 名稱(如print),然後一個點,然後 類名(例如: print.glm
  • 一些準備必須已經 做這個通用名稱(print) 這個工作,但如果你 只是希望自己符合 現有方法的名稱,你不需要 這個(見我refered到 的幫助,如果你前面做)。

到了旁觀者的眼睛,特別是新創建的時髦模型擬合包的用戶,它是能夠鍵入predict(myfit, type="class")predict.mykindoffit(myfit, type="class")方便多了。

還有很多,但這應該讓你開始。這種基於對象的屬性(類)的調度方法存在很多缺點(並且C純粹主義者可能在晚上驚慌失措地對其進行了清醒),但是對於很多情況,它運行得體。使用當前版本的R,已經實現了更新的方法(S4和參考類),但大多數人仍然(僅)使用S3。

37

爲了讓您開始使用S3,請查看median函數的代碼。在命令提示鍵入median揭示,它具有在其主體的一行,即

UseMethod("median") 

這意味着,它是一個S3方法。換句話說,對於不同的S3類你可以有不同的median函數。要列出所有可能的中位數法,鍵入

methods(median) #actually not that interesting. 

在這種情況下,只有一個方法,默認,這就是所謂的任何東西。您可以通過鍵入

median.default 

一個更有趣的例子是print功能,其中有許多不同的方法看看它的代碼。

methods(print) #very exciting 

請注意,某些方法的名稱旁邊有*。這意味着它們隱藏在某個包的名稱空間內。使用find找出他們是在哪個包。例如

find("acf") #it's in the stats package 
stats:::print.acf 
6

嘗試

methods(residuals) 

列出,除其他外, 「residuals.lm」 和 「residuals.glm」。這意味着當你安裝了線性模型m並輸入residuals(m)時,residuals.lm將被調用。當你擬合了一個廣義線性模型時,residuals.glm將被調用。 它是顛倒了C++對象模型的一種。在C++中,您可以定義一個具有虛擬函數的基類,這些基類會被派生分類覆蓋。 在R中你定義了一個虛擬(aka泛型)函數,然後你決定哪個類將會覆蓋這個函數(又名定義一個方法)。請注意,這樣做的類不需要從一個普通的超類派生。 我不同意一般比S3更喜歡S3。 S4有更多的形式主義(=更多的打字),這對某些應用來說可能太多了。然而,S4類可以像C++中的類或結構一樣定義。您可以指定某一個類的對象是由一個字符串,例如兩個數字:

setClass("myClass", representation(label = "character", x = "numeric", y = "numeric")) 

方法是所謂的與類的一個對象可以依靠其成員的對象。這與S3類非常不同,它們只是一系列元素的列表。

使用S3和S4,您可以通過fun(object, args)而不是object$fun(args)來調用成員函數。如果你正在尋找類似於後者的東西,看看proto軟件包。

+0

我敢肯定的成員函數和屬於對象的方法的想法,並不意味着在R.方法太大的意義不屬於對象(也函數是對象太),但屬於功能。 – petermeissner

+0

[see here](http://adv-r.had.co.nz/OO-essentials.html#s3) – petermeissner

10

我來到這個問題,主要想知道名字來自哪裏。從this wikipedia article看來,該名稱是指R所基於的S編程語言的版本。其他答案中描述的方法調度方案來自S並根據版本進行適當標記。

27

http://adv-r.had.co.nz/OO-essentials.html

[R三大OO系統的不同之處是如何類和方法的定義:

  • S3實現面向對象編程的風格被稱爲通用的功能OO。 這與大多數編程語言不同,例如Java,C++和實現消息傳遞OO的C#。通過消息傳遞,消息 (方法)被髮送到對象,並且對象確定調用哪個函數 。通常,該對象在方法 調用中具有特殊外觀,通常出現在方法/消息的名稱之前:例如, canvas.drawRect(「blue」)。 S3是不同的。儘管通過方法執行計算仍然是 ,但稱爲通用函數的特殊類型函數決定調用哪種方法,例如drawRect(canvas,「blue」)。 S3是一個非常隨意的系統。它沒有正式的類定義。

  • S4與S3類似,但更爲正式。 S3有兩個主要差異 。S4具有正式的類定義,它描述了每個類的表示和繼承,並且具有用於定義泛型和方法的特殊幫助函數 。 S4還具有多個 調度,這意味着通用函數可以根據任何數量的參數類而不僅僅是一個類選擇方法。

  • 參考類,簡稱RC,與S3 和S4完全不同。 RC實現消息傳遞OO,因此方法屬於 類,而不屬於函數。 $用於分隔對象和方法,因此 方法調用看起來像canvas $ drawRect(「blue」)。 RC對象也是 mutable:它們不使用R的通常修改拷貝語義,但是已經修改了 。這使得他們更難推理,但允許他們解決難以用S3或S4解決的問題。

還有另外一個系統,不是很面向對象,但要在這裏提到這一點很重要 :

  • 基本類型,所依據的其他OO 系統內部C級類型。基本類型大多使用C代碼進行操作,但它們對於知道的重要性很大,因爲它們爲其他面向對象系統提供了 的構建塊。