8

假设与特定 S4 通用函数/方法关联的所有S4 方法共享一个应该具有特定默认值的形式参数。直观地说,我会在 S4泛型的定义中陈述这样一个论点(而不是在每个方法定义中陈述它,这对我来说似乎有些多余)。

但是,我注意到这样我遇到了麻烦,因为似乎形式参数的默认值没有分派给方法,因此引发了错误。

这不是有点反对结合泛型和方法的想法吗?当默认值始终相同时,为什么我必须再次在每个方法中分别声明形式参数?我可以以某种方式显式分派形式参数的默认值吗?


您将在下面找到该行为的简短说明

通用函数

setGeneric(
    name="testFoo",
    signature=c("x", "y"),
    def=function(
        x,
        y,
        do.both=FALSE,
        ...
    ) {
    standardGeneric("testFoo")       
    }
)

方法

setMethod(
    f="testFoo", 
    signature=signature(x="numeric", y="numeric"),
    definition=function(
        x,
        y
    ) { 
    if (do.both) {
        out <- list(x=x, y=y)
    } else {
        out <- x
    }
    return(out)
    }
)

错误

> testFoo(x=1, y=2)
Error in .local(x, y, ...) : object 'do.both' not found

do.both修复它的冗余声明

setMethod(
    f="testFoo", 
    signature=signature(x="numeric", y="numeric"),
    definition=function(
        x,
        y,
        do.both=FALSE
    ) { 
    if (do.both) {
        out <- list(x=x, y=y)
    } else {
        out <- x
    }
    return(out)
    }
)

> testFoo(x=1, y=2)
[1] 1
4

1 回答 1

9

当你调用 时testFoo(x=1, y=2),它首先由 S4 泛型处理,它查找一个方法,找到它,然后向它分派一个如下所示的调用testFoo(x=1, y=2, do.both=FALSE, ...)

用以下话说?standardGeneric

'standardGeneric' 调度为名为'f' 的通用函数定义的方法,使用调用它的框架中的实际参数。

如果它派发该调用的方法不接受do.both参数,则该方法 ---就像任何其他 R 函数一样--- 抛出错误。没有函数可以处理包含参数的调用,foo除非它的函数定义包含 (a) 形式参数foo或 (b) “点”参数...,它可以吸收任意提供的参数。

基本上你所尝试的与以下没有什么不同,它以类似但可能更容易看到的方式失败:

testFooGeneric <- function(x=1, y=2, do.both=FALSE, ...) {
    ## The line below does essentially what standardGeneric() does
    if(is.numeric(x) & is.numeric(y)) {
        testFooMethod(x=x, y=y, do.both=do.both)
    }
}

testFooMethod <- function(x, y) {
    cat("Success!\n")
}

testFooGeneric(x=1, y=2)
# Error in testFooMethod(x = x, y = y, do.both = do.both) : 
#   unused argument(s) (do.both = do.both)

要解决上述问题,您需要testFooMethod()通过以下两种方式之一重新定义,其中任何一种都可以修复您的 S4 方法:

## Option 1
testFooMethod <- function(x, y, do.both) {
    cat("Success!\n")
}
testFooGeneric(x=1, y=2)
# Success!

## Option 2
testFooMethod <- function(x, y, ...) {
    cat("Success!\n")
}
testFooGeneric(x=1, y=2)
## Success!
于 2012-09-18T22:20:57.370 回答