有没有办法定义方法的论点是 缺失或无效?

在下面的示例中,无论我是否输入,我都想调用相同的功能 foo() 或者 foo(NULL). 。我当然知道我可以有一种方法 setMethod("foo","NULL",function(x) foo()) 但这是代码复制和可能的错误来源。

谢谢!

setGeneric("foo",function(x) standardGeneric("foo"))
setMethod("foo","numeric",function(x) "numeric")
setMethod("foo","NULL",function(x) "NULL")
setMethod("foo","missing",function(x) "missing")

R> foo(1)
[1] "numeric"
R> foo()
[1] "missing"
R> foo(NULL)
[1] "NULL"
有帮助吗?

解决方案

聚会迟到了几乎三年,但您真的想要 setClassUnion:

> setClassUnion("missingOrNULL", c("missing", "NULL"))
> setGeneric("foo",function(x) standardGeneric("foo"))
> setMethod("foo","numeric",function(x) "numeric")
> setMethod("foo","missingOrNULL",function(x) "NULL")

> foo(1)
[1] "numeric"
> foo()
[1] "NULL"
> foo(NULL)
[1] "NULL"

setClassUnion 创建一个虚拟类,该类是一个超级阶级(父母)到组件类,因此两个孩子都从该类中继承,这意味着您可以针对每个孩子分发相同的功能。

其他提示

使用 setMethod("foo","NULL",function(x) foo()) 不是代码复制,因为您不复制代码,而是对其进行调用。我会说这是解决您的问题的一个很好的方法。

我想适当的方法是在签名中使用“任何”:

setGeneric("foo",function(x) standardGeneric("foo"))
setMethod("foo","numeric",function(x) "numeric")
setMethod("foo","ANY",function(x) "ANY")

> foo(1)
[1] "numeric"

> foo()
[1] "ANY"

> foo(NULL)
[1] "ANY"

确保您指定要照顾的所有其他可能性,因为“任何”也将其余的所有不适合其他方法的签名。

如果您的参数可能丢失,则不能在setMethods的签名中指定它们,而是在通用中设置默认值。这是 - 在我谦虚的角度 - 一个更好的设计选择。

setGeneric("foo",function(x,y=NULL,...) {
        standardGeneric("foo")
    })

setMethod("foo",c("numeric","ANY"),function(x,y,...) {
            print(y)
    })
setMethod("foo",c("numeric","numeric"),function(x,y,...) {
            x + y
    })

> foo(1)
NULL

> foo(1,3)
[1] 4

> foo(1,NULL)
NULL

现在,您可以像缺少的参数一样处理无效的案例中的编码。

在旁注上:现在,我添加了null作为默认值,但是在许多情况下,对于默认值有更明智的选择。只需记住,SetMethod采用初始签名,并且当将y设置为null时,它不会被默认值替换。

例如:

setGeneric("bar",function(x,y=2,...) {
        standardGeneric("bar")
    })

setMethod("bar",c("numeric","ANY"),function(x,y,...) {
            x + y
    })
setMethod("bar",c("numeric","numeric"),function(x,y,...) {
            x - y
    })

> bar(1)
[1] 3

> bar(1,2)
[1] -1

> bar(1,NULL) # this y is not replaced with the default!
numeric(0)

肮脏的黑客:

我发现该方法有点尴尬,但是这是一个肮脏的黑客,将所有缺失的参数设置为null:

setGeneric("foo",function(x,y,z) {
    pars <- names(formals(foo))
    for(i in pars){
        tryerr <- try(get(i),silent=T)
        if(is(tryerr,"try-error")){ assign(i,NULL)}
    }
    standardGeneric("foo")
}

尝试这个,你得到:

> foo(1)
[1] "numeric"

> foo(NULL)
[1] "NULL"

> foo()
[1] "NULL"

因此,您再也不会派遣失踪了。您可以忘记它。但这不是做事的适当方式...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top