Более каноническое решение будет выглядеть следующим образом:
operation <- function(x, ...) {
dots <- list(...)
x^dots[[1]]
}
, но если вы знаете достаточно, чтобы сказать, что требуемый аргумент является первым аргументом, переданным как ...
, то вам следует сделать этот аргумент.Поскольку ваш код (и мой) не будет работать, например, при следующем вызове:
> operation(1:10, foo = "bar", b = 2)
Error in x^dots[[1]] : non-numeric argument to binary operator
Если вы возьмете ...
, как у меня выше, тогда вы можете извлечь нужный аргумент, если онnamed:
operation <- function(x, ...) {
dots <- list(...)
want <- which(names(dots) == "b")
stopifnot(length(want) > 0)
b <- dots[[want]]
x^b
}
, который работает следующим образом:
> operation(1:10, foo = "bar", b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
, но все равно не работает, если b
не является именованным аргументом:
> operation(1:10, foo = "bar", 2)
Error: length(want) > 0 is not TRUE
Так что выПридуманный вариант может сработать в одном случае использования, который вы представляете, но это не более общая стратегия для того, что вы хотите сделать.Что должен сделать operation
, если не переданы дополнительные аргументы?В вашем коде предполагается, что есть другие аргументы и, как таковые, больше не являются необязательными, как вы и указали.Если b
должно принимать какое-то другое значение по умолчанию, если задано non, тогда все становится проще:
operation <- function(x, b = 1) {
x^b
}
sjbDo <- function(FUN, x, ...) {
## function matching
FUN <- match.fun(FUN)
# run the operation on x
xvec <- FUN(x, ...)
xvec
}
, что дает:
> sjbDo(operation, 1:10)
[1] 1 2 3 4 5 6 7 8 9 10
> sjbDo(operation, 1:10, b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
> sjbDo("operation", 1:10, b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
Последнее работает из-за использованияиз match.fun
.
Суть вышесказанного в том, что я не думаю, что вы хотите, чтобы operation()
имел аргумент ...
, потому что я не понимаю, как такой код мог бы работать.Я думаю, что вам нужен способ написать внешний вызов функции sjbDo()
, чтобы иметь несколько именованных аргументов и передать любые другие аргументы в функцию, которую вы хотите вызвать в sjbDo()
, которую я вызываю здесь FUN
, и выс именем operation
.
Другими словами, я думаю, что вам нужна оболочка (sjbDo()
), которая может вызывать данную функцию (предоставляется в качестве аргумента FUN
) с аргументом x
плюс любойдругие аргументы, которые FUN
требует, не думая обо всех возможных аргументах FUN
потребует?