在单个函数中组合S4和S3方法

时间:2012-08-23 22:25:16

标签: r cran s4

定义一个应该具有S3和S4类实现的通用函数的好方法是什么?我一直在使用这样的东西:

setGeneric("myfun", function(x, ...){  
    standardGeneric("myfun");
});

setMethod("myfun", "ANY", function(x, ...) {
    if(!isS4(x)) {
        return(UseMethod("myfun"));
    }
    stop("No implementation found for class: ", class(x));
});

这成功了:

myfun.bar <- function(x, ...){
    return("Object of class bar successfully dispatched.");
}
object <- structure(123, class=c("foo", "bar"));
myfun(object)

是否有举动&#34;本地&#34;要做到这一点的方法?我知道我们可以使用setOldClass为S3类定义S4方法,但是这样我们就失去了S3方法调度,以防对象有多个类。例如。 (在一个干净的会议中):

setGeneric("myfun", function(x, ...){  
    standardGeneric("myfun");
});

setOldClass("bar")
setMethod("myfun", "bar", function(x, ...){
    return("Object of class bar successfully dispatched.");
});

object <- structure(123, class=c("foo", "bar"));
myfun(object)

此操作失败,因为忽略了第二类object,在本例中为bar。我们可以通过在foobar之间定义正式的S4继承来解决这个问题,但是对于我的应用程序,我宁愿希望myfun.bar在带有类{{{1}的S3对象上开箱即用。 1}}。

无论哪种方式,事情都变得混乱,我想这是一个常见问题,所以可能有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:18)

方法的“S3通用函数的方法”部分提出了S3泛型,S4类的S3式方法和S4方法本身。

setClass("A")                    # define a class

f3 <- function(x, ...)           # S3 generic, for S3 dispatch    
    UseMethod("f3")
setGeneric("f3")                 # S4 generic, for S4 dispatch, default is S3 generic
f3.A <- function(x, ...) {}      # S3 method for S4 class
setMethod("f3", "A", f3.A)       # S4 method for S4 class

需要S3泛型来分派S3类。

setGeneric()将f3(即S3泛型)设置为默认值,而f3,ANY-method实际上是S3泛型。由于“ANY”位于类层次结构的根(类),因此S4方法不存在的任何对象(例如,S3对象)最终都是S3泛型。

帮助页面上描述了S4类的S3泛型的定义?方法。我认为,大约S3,S3不知道S4方法,所以如果一个调用S3泛型(例如,因为一个在包名称空间中,包知道S3 f3而不是S4 f3)f3泛型找不到S4方法。我只是信使。