2013-10-08 3 views
0

Я хотел бы написать функцию-оболочку для двух функций, которые принимают необязательные аргументы.Как передать альтернативные аргументы через функцию обертки?

Вот пример функции fun обернуть funA и funB

funA <- function(x = 1, y = 1) return(x+y) 
funB <- function(z = c(1, 1) return(sum(z)) 

fun <- function(x, y, z) 

Я хотел бы fun вернуть x+y если x и y предусмотрены, и sum(z) если вектор z предоставляется.

Я попытался увидеть, как функция lm принимает такие необязательные аргументы, но неясно, как именно используется, например, match.call.

После нахождения связанных вопросов (например, How to use R's ellipsis feature when writing your own function? и using substitute to get argument name with)), я придумал приемлемое решение.

Мое решение только в том, чтобы использовать

fun <- function(...){ 
    inputs <- list(...) 
    if (all(c("x", "y") %in% inputs){ 
    ans <- funA(x, y) 
    } else if ("z" %in% inputs){ 
    ans <- funB(z) 
    } 

Есть ли лучший способ?

Примечание: Возможно, этот вопрос может быть закрыт в двух экземплярах, но, надеюсь, он может служить цели в руководстве других пользователей хорошее решение: было бы полезно расширили свой поиск по-разному относятся ellipsis, substitute , в дополнение к match.call.

+0

@agstudy Я нашел часть полезного решения, но хотел бы знать более надежный подход. –

ответ

3

Использование missing. Это возвращает funA(x, y) если оба x и y предоставляются и возвращает funB, если они не являются, но z предоставляется, и если ни один из них не предусмотрены возвращается NULL:

fun <- function(x, y, z) if (!missing(x) && !missing(y)) { 
      funA(x, y) 
     } else if (!missing(z)) funB(z) 

Это, кажется, ответить на ваш вопрос, как указано, но обратите внимание, что аргументы по умолчанию в funA и funB никогда не используются, поэтому, возможно, вы действительно хотели что-то другое?

Замечание fun, которое задано в вопросе, работает только в том случае, если аргументы названы, тогда как fun работает, даже если они предусмотрены позиционно.

+0

Я не хочу использовать значения по умолчанию, я просто помещаю их для иллюстрации (например, что одна функция принимает два числа, а другой - вектор) –

2

Я бы хотел, например, использовать это с помощью match.call. Это похоже на ваше решение, но более надежное.

fun <- function(...){ 
    arg <- as.list(match.call())[-1] 
    f <- ifelse(length(arg)>1,"funA","funB") 
    do.call(f,arg) 
} 

fun(x=1,y=2) ## or fun(1,2) no need to give named arguments 
[1] 3 
> fun(z=1:10) ## fun(1:10) 
[1] 55 
Смежные вопросы