Rap*_*ter 8 methods r default-value s4
假设与特定S4泛型函数/方法关联的所有 S4方法共享一个应该具有特定默认值的形式参数.直觉上,我会在S4 泛型的定义中陈述这样一个论点(而不是在每个方法定义中陈述它对我来说似乎有点多余).
但是,我注意到这种方式我遇到了麻烦,因为似乎没有将形式参数的默认值分派给方法,因此抛出了错误.
这有点不符合通用和方法相结合的想法吗?当默认值始终相同时,为什么我必须再次分别在每个方法中声明形式参数?我可以以某种方式明确地发送正式参数的默认值吗?
您可以在下面找到该行为的简短说明
setGeneric(
name="testFoo",
signature=c("x", "y"),
def=function(
x,
y,
do.both=FALSE,
...
) {
standardGeneric("testFoo")
}
)
Run Code Online (Sandbox Code Playgroud)
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)
}
)
Run Code Online (Sandbox Code Playgroud)
> testFoo(x=1, y=2)
Error in .local(x, y, ...) : object 'do.both' not found
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
当你调用时testFoo(x=1, y=2),它首先由S4泛型处理,它寻找一个方法,找到它,并向它发送一个看起来像这样的调用:testFoo(x=1, y=2, do.both=FALSE, ...).
用下面的话说?standardGeneric:
'standardGeneric'使用调用它的帧中的实际参数调度为名为'f'的泛型函数定义的方法.
如果该方法与它分派该呼叫不采取一个do.both参数,方法--- 就像任何其它的R功能 ---抛出一个错误.没有函数可以处理包含参数的调用,foo除非它的函数定义包含(a)形式参数foo或(b)"dots"参数...,它可以吸收任意提供的参数.
基本上你所尝试的与以下内容没有什么不同,后者以类似但可能更容易看到的方式失败:
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)
Run Code Online (Sandbox Code Playgroud)
要解决上述问题,您需要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!
Run Code Online (Sandbox Code Playgroud)