используя ... аргумент inline - PullRequest
1 голос
/ 14 марта 2011

У меня есть следующая функция

sjbDo <- function(operation, x, statelist, Spos, isFuture = FALSE) {

  # run the operation on x
  xvec <- operation(x);

  # and so on

}

и я мог бы назвать это так:

A <- sjbDo( function(x) {x}, statelist$A, statelist, 1)

Однако я хочу изменить sjbDo, чтобы встроенная функция могла принимать дополнительные аргументы. Что-то вроде:

kTheta <- sjbDo( function(x, b) {x^b}, statelist$K, statelist, 1, FALSE, b=theta.k)

Я пытался

sjbDo <- function(operation, x, statelist, Spos, isFuture = FALSE, ...) {

  # run the operation on x
  xvec <- operation(x,...);

Но, похоже, это не работает. Как я могу заставить это работать?

Ответы [ 2 ]

6 голосов
/ 14 марта 2011

Более каноническое решение будет выглядеть следующим образом:

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 потребует?

0 голосов
/ 14 марта 2011

Упс, я разобрался

операция <- функция (x, ...) {x ^ ... [[1]]} </p>

В любом случае, спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...