当显式将参数值分配给给定S4方法中的后续S4方法时,如何避免经典Error: argument "<argname>" is missing, with no default
错误(参见下面的示例)。
foo()
的方法bar()
。 x
和y
。 foo()
以显式方式将参数x
和y
发送至bar()
:bar(x=x, y=y)
。现在,关键点在于我不希望foo()
关注是否缺少传递给bar()
的任何或所有参数。
setGeneric(
name="foo",
signature=c("x", "y"),
def=function(x, y, ...) {
standardGeneric("foo")
}
)
setGeneric(
name="bar",
signature=c("x", "y"),
def=function(x, y, ...) {
standardGeneric("bar")
}
)
bar()
setMethod(
f="bar",
signature=signature(x="missing", y="missing"),
definition=function(x, y, ...) {
print("Doing what I'm supposed to do when both args are missing")
return(NULL)
}
)
setMethod(
f="bar",
signature=signature(x="ANY", y="missing"),
definition=function(x, y, ...) {
message("'y' is missing, but I can give you 'x':")
print(x)
return(NULL)
}
)
setMethod(
f="bar",
signature=signature(x="missing", y="ANY"),
definition=function(x, y, ...) {
message("'x' is missing, but I can give you 'y':")
print(y)
return(NULL)
}
)
setMethod(
f="bar",
signature=signature(x="ANY", y="ANY"),
definition=function(x, y, ...) {
message("x:")
print(x)
message("y:")
print(y)
return(NULL)
}
)
foo()
如上所述,我不希望foo()
关注是否遗漏了传递给bar()
的任何或所有参数。它应该以明确的方式将所有内容传递给bar()
:
setMethod(
f="foo",
signature=signature(x="ANY", y="ANY"),
definition=function(x, y, ...) {
bar(x=x, y=y)
}
)
方法def在第一眼看上去可能看起来不错,但如果调用它时x
或y
丢失则会失败:
> foo(x="Hello", y="World!")
x:
[1] "Hello"
y:
[1] "World!"
NULL
> foo(x="Hello")
Error in bar(x = x, y = y) :
error in evaluating the argument 'y' in selecting a method for function 'bar': Error: argument "y" is missing, with no default
> foo()
Error in bar(x = x, y = y) :
error in evaluating the argument 'x' in selecting a method for function 'bar': Error: argument "x" is missing, with no default
到目前为止,这是我能提出的唯一解决方法:
setMethod(
f="foo",
signature=signature(x="ANY", y="ANY"),
definition=function(x, y, ...) {
if (missing(x) && missing(y)) {
bar()
} else if (missing(x)) {
bar(y=y)
} else if (missing(y)) {
bar(x=x)
} else {
bar(x=x, y=y)
}
}
)
> foo(x="Hello", y="World!")
x:
[1] "Hello"
y:
[1] "World!"
NULL
> foo(x="Hello")
'y' is missing, but I can give you 'x':
[1] "Hello"
NULL
> foo(y="World!")
'x' is missing, but I can give you 'y':
[1] "World!"
NULL
> foo()
[1] "Doing what I'm supposed to do when both args are missing"
NULL
它有效,但由于所有if ... else
语句,我不太喜欢它。整个&#34; if-else逻辑&#34;已经进入了bar()
的各种方法的规范。毕竟,首先要有一个方法调度员,对吧?因此,我会将这些陈述视为&#34;不受欢迎的工作&#34;我正在寻找更好的方法。
当然,人们可以使用NULL
作为所有&#34;关键&#34;的默认值。参数,但我希望尽可能依赖missing()
代替is.null()
。
答案 0 :(得分:4)
这是另一种想法。 (它广泛受到许多R模型拟合函数所使用的“语言计算”的启发。)
setMethod(
f="foo",
signature=signature(x="ANY", y="ANY"),
definition=function(x, y, ...) {
mc <- match.call()
mc[[1]] <- quote(bar)
eval(mc)
}
)
foo(x="Hello")
# 'y' is missing, but I can give you 'x':
# [1] "Hello"
# NULL
foo(y="World")
# 'x' is missing, but I can give you 'y':
# [1] "World"
# NULL
foo()
# [1] "Doing what I'm supposed to do when both args are missing"
# NULL