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

Jer*_*oen 13 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));
});
Run Code Online (Sandbox Code Playgroud)

这成功了:

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

是否有一种"原生"方式来实现这一目标?我知道我们可以使用S3类定义S4方法setOldClass,但是这样我们就失去了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)
Run Code Online (Sandbox Code Playgroud)

这会失败,因为object在这种情况下bar,第二类被忽略.我们可以通过在foo和之间定义正式的S4继承来解决这个问题bar,但是对于我的应用程序,我宁愿myfun.bar在一个类的S3对象上开箱即用bar.

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

Mar*_*gan 19

方法的"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
Run Code Online (Sandbox Code Playgroud)

调度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方法.我只是信使.