我正在编写一个S3方法,我想使用任何 R对象,包括S4对象。
我不明白的第一件事是S4类似乎不是从S4基类派生的,所以给定f <- function(x) UseMethod("f")
我不能只声明f.S4
调度方法并且有它拾取所有S4对象。 (虽然如果unclass
是一个S4对象,它似乎确实被赋予了类S4
。)我应该如何管理调度?
似乎处理这些S4对象的最简单方法是将它们转换为列表。不幸的是,as.list
会抛出一个错误(“没有方法可以将这个S4类强制转换为向量”)。
这是我的测试S4对象:
library(gWidgetstcltk)
win <- gwindow()
S3Part
包中的函数S3Class
和methods
看起来很有希望,但是当我在win
上使用它们时,它们都会抛出错误。因此,问题2是:是否有将S4对象转换为列表的一般方法?
答案 0 :(得分:6)
S4是一个超类(虚拟类,无论如何,有人请用正确的名称编写),不能直接调度使用。顺便说一下S3也一样。您可以像对S3类一样对S4类进行S3调度。在旁注中,如果未指定任何内容,则在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方法,可以使用isS4()
在.default函数或泛型函数中手动分派。在.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对象。