У меня есть общая функция 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)
иначе 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. - person Thomas   schedule 08.08.2018