2011-05-06 63 views
6

我在寫S3方法,我想與任何 R對象一起使用,包括S4對象。你如何獲得S3方法使用S4對象?

我不明白的第一件事是S4類似乎不是從S4基類派生的,所以給出f <- function(x) UseMethod("f")我不能只聲明f.S4調度方法並讓它拾取所有S4對象。 (雖然如果unclass是S4對象,但看起來好像是S4類。)我應該如何管理調度?

看來,處理這些S4對象的最簡單方法是將它們轉換爲列表。不幸的是,as.list會拋出一個錯誤(「沒有任何方法強迫這個S4類到一個向量」)。

這是我的測試S4對象:

library(gWidgetstcltk) 
win <- gwindow() 

功能S3PartS3Classmethods包看起來前途無量,但他們都拋出錯誤,當我使用它們win。所以,問題2是:是否有將S4對象轉換爲列表的一般方法?

回答

6

S4是無法直接調度使用的超類(虛擬類,無論有人請用正確的名稱)。順便說一句。您可以像使用S3類一樣執行S3派發S4類。在旁註中,如果沒有指定任何內容,則在S4對象上調用myfun只會導致.default函數。 :

myfun <- function(object, ...) UseMethod("myfun") 

myfun.default <- function(object,...){ 
    cat("default method.\n") 
    print(object) 
} 

myfun.gWindow <- function(object,...){ 
    cat("Here here...") 
    print(object) 
} 

x <- 1:10 
myfun(x) 
myfun(win) 
rm(myfun.gWindow) 
myfun(win) 

如果你想趕上所有S4方法,您可以手動調度在.DEFAULT功能或通用的功能,採用isS4()。在.default函數中添加調度允許自動將S3調度到某些S4類。如果您在通用加它,你只要發往所有S4無事,是什麼:

myfun.default <- function(object,...){ 
     if(isS4(object)) myfun.S4(object,...) 
     else { 
      cat("default method.\n") 
      print(object) 
     } 
    } 

    myfun.S4 <- function(object,...){ 
     cat("S4 method\n") 
     print(object) 
    } 

x <- 1:10 
myfun(x) 
myfun(win) 

關於你提到的第二個問題:gWindow是一個特例。當使用str(win)進行嘗試時,它也會返回錯誤。我不知道確切的結構,但絕對不是一個正常的S4對象。

+0

謝謝。調度現在更有意義。看起來我偶然發現了一個棘手的測試案例;將不得不嘗試其他幾個人並進一步調查。 – 2011-05-06 16:20:27

+0

gwindow對象確實是一個不好的例子。我相信我爲gWidgets對象定義的長度方法會擾亂str。 gwindow對象有兩個插槽,一個用於存放一個工具包(gWidgetsXXX包用於方法調度),另一個用於gWidgetsXXX包中的對象。然而,喬里斯正在展示要做什麼。有一個gWindow的超類,可以用來抓別人。 – jverzani 2011-05-06 16:33:13

+0

@John:謝謝你的澄清。我會集中精力解決更簡單的案例。 – 2011-05-08 19:48:40