【问题标题】:Combining S4 and S3 methods in a single function在单个函数中结合 S4 和 S3 方法
【发布时间】:2012-08-23 22:25:16
【问题描述】:

什么是定义通用函数的好方法,它应该具有 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)

是否有移动“本地”方式来完成此任务?我知道我们可以使用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 能够在具有bar 类的S3 对象上开箱即用。

不管怎样,事情变得一团糟,我想这是一个常见的问题,所以可能有更好的方法来做到这一点?

【问题讨论】:

标签: r cran s4


【解决方案1】:

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

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

【讨论】:

  • 那么这是否意味着首先根据签名找出 S4 方法,如果匹配失败,然后分派 S3 方法?
  • 能否详细说明为什么需要第一行和最后一行?
猜你喜欢
  • 2020-02-29
  • 2012-02-11
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多