14

什么是定义应该具有 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)

有没有一种“本机”的方式来实现这一点?我知道我们可以使用 为 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)

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

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

4

1 回答 1

19

?Methods 的“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 方法实际上是 S3 泛型。由于“ANY”位于(某种程度)类层次结构的根部,因此任何不存在 S4 方法的对象(例如,S3 对象)都将在 S3 泛型处结束。

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

于 2012-08-23T23:09:42.077 回答