Функция R избавляется от неиспользуемых параметров в

#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. Это ваш выбор. Это был бы не мой выбор.