【发布时间】:2018-08-08 19:58:07
【问题描述】:
我有一个通用函数foo,我想根据给定的参数调用三种不同的方式。
foo <- function(...) UseMethod("foo")
#default
foo.default <- function(x, y, ...) {
#does some magic
print("this is the default method")
}
#formula
foo.formula <- function(formula, data = list(), ...) {
print("this is the formula method")
}
#data.frame
foo.data.frame <- function(data, x, y, ...) {
print("this is the data.frame method")
}
在下面我将展示我是如何期望方法分派工作的,但输出显示在每个调用下...
mydata <- data.frame(x=c(1,2,3,4),y=c(5,6,7,8))
#ways to call default function
foo(x = mydata$x, y = mydata$y)
#[1] "this is the default method"
#ways to call formula
foo(formula = mydata$x~mydata$y)
#[1] "this is the formula method"
foo(formula = x~y, data = mydata)
#[1] "this is the formula method"
foo(data = mydata, formula = x~y) #ERROR
#[1] "this is the data.frame method"
#ways to call data.frame method
foo(data = mydata, x = x, y = y)
#[1] "this is the data.frame method"
foo(x = x, y = y, data = mydata) #ERROR
#Error in foo(x = x, y = y, data = mydata) : object 'x' not found
据我所知,使用的方法取决于第一个参数的类。本质上,我希望方法分派取决于传递的参数 到通用函数foo 而不是第一个参数。
我希望调度具有以下优先级:
如果公式参数存在,则使用公式方法(数据参数在这里应该是可选的)
然后,如果没有找到公式参数,如果存在数据参数,则使用 data.frame 方法(需要 x 和 y 参数)
else foo 需要 x 和 y 参数,否则会失败。
注意
我想避免如下定义泛型函数foo
foo <- function(formula, data,...) UseMethod("foo")
虽然这将解决我的所有问题(我相信除了最后一种情况之外的所有问题),但这将导致devtools::check() 警告,因为某些 S3 函数将不会具有与通用函数相同的参数并且将不再一致(特别是 foo.default 和 foo.data.frame)。而且我不想包含缺少的参数,因为这些方法对这些参数没有用处。
【问题讨论】:
-
重要的是签名中的第一个命名参数,而不是它们被调用的顺序。对于
foo(a,b) {...}、foo(a = 1, b = 2)和foo(b = 2, a = 1),根据类分派到相同的方法a。通常,您正在寻找多重调度,它仅在 S4 中可用,在 S3 中不可用。
标签: r methods arguments dispatch