#r
#r
Вопрос:
У меня есть основная функция mainFunction
, которая вызывает подфункции :
subFunctionA
subFunctionB
subFunctionC
В идеале я бы хотел не устанавливать вручную все имена «дополнительных» параметров в моей mainFunction
подписи, а использовать ...
вместо этого. Однако я получаю сообщение об unused argument
ошибке :
# Initial try
subFunctionA <- function(a = 1, b = 2) {a b}
subFunctionB <- function(aa = 1, bb = 2) {aa bb}
subFunctionC <- function(a = 1, bb = 2) {a bb}
mainFunction <- function(...) {
x1 <- subFunctionA(...)
x2 <- subFunctionB(...)
x3 <- subFunctionC(...)
x1 x2 x3
}
mainFunction(a = 2, b = 2, aa = 3, bb = 4)
# Return error "Error in subFunctionA(...) : arguments inutilisés (aa = 3, bb = 4)"
Ниже приведен обходной путь, который я использую, но я не уверен, что хорошо использую дополнительные параметры :
# Workaround
parameters_filters <- function(fun, ...) {
p <- list(...)
p[which(names(p) %in% names(as.list(args(fun))))]
}
mainFunction_workaround <- function(...) {
x1 <- do.call(subFunctionA, parameters_filters(subFunctionA, ...))
x2 <- do.call(subFunctionB, parameters_filters(subFunctionB, ...))
x3 <- do.call(subFunctionC, parameters_filters(subFunctionC, ...))
x1 x2 x3
}
mainFunction_workaround(a = 2, b = 2, aa = 3, bb = 4)
# Returns 17
Есть ли «более чистый» способ сделать это?
Ответ №1:
Вы были почти на месте с первой попыткой:
subFunctionA <- function(a = 1, b = 2, ...) {a b}
subFunctionB <- function(aa = 1, bb = 2, ...) {aa bb}
subFunctionC <- function(a = 1, bb = 2, ...) {a bb}
mainFunction <- function(...) {
x1 <- subFunctionA(...)
x2 <- subFunctionB(...)
x3 <- subFunctionC(...)
x1 x2 x3
}
mainFunction(a = 2, b = 2, aa = 3, bb = 4)
#[1] 17
Это вызовет проблемы, если пользователь использует позиционные аргументы:
mainFunction(2, 2, 3, 4)
#[1] 12
Таким образом, я бы избегал ...
в основной функции (если у вас на самом деле нет необязательных параметров):
mainFunction <- function(a, b, aa, bb) {
args <- list(a = a, b = b, aa = aa, bb = bb)
x1 <- do.call(subFunctionA, args)
x2 <- do.call(subFunctionB, args)
x3 <- do.call(subFunctionC, args)
x1 x2 x3
}
mainFunction(2, 2, 3, 4)
#[1] 17
И, конечно, не использовать ...
здесь вообще было бы самым безопасным вариантом.
Комментарии:
1. Спасибо за ответ. Я понимаю, что избегание
...
было бы самым безопасным вариантом, но я знаю, что мои вспомогательные функции, вероятно, изменятся в будущем, и я не хочу менятьсяmainFunction
, как только изменится сигнатура вспомогательной функции.2. Это ваш выбор. Это был бы не мой выбор.