我有一个通用函数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
的参数,而不是第一个参数。我希望分派具有以下优先级:
如果存在formula参数,则使用formula方法(data参数应该是可选的)
然后,如果没有找到formula参数,如果存在data参数,则使用data.frame方法(需要x和y参数)
否则,
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。 - Thomas