R: указание строки в качестве аргумента функции, которая вызывает другую функцию - PullRequest
8 голосов
/ 10 февраля 2011

Это вопрос касательно кодирования в R.

Приведенный мною пример - дидактический. Предположим, у меня есть функции с именами «func1» и «func2», где каждый принимает два аргумента (скажем, скаляры). Я хочу указать другую функцию 'applyfunction', которая имеет три аргумента: последний номер используемой функции ('1' или '2') и два аргумента для функции. Например, я хочу сделать что-то вроде этого (что, конечно, не работает):

applyfunction(1,2,3), где он будет эффективно работать func1(2,3) и

applyfunction(2,9,43), где он будет эффективно работать func2(9,43).

Есть идеи?

Best, DB

Ответы [ 5 ]

7 голосов
/ 10 февраля 2011

Возможно, вы захотите взглянуть на do.call(), который вызывает функцию с аргументами, представленными в списке.Нетрудно написать обертку вокруг этого, которая делает именно то, что вы хотите.

function1=function(a,b)a+b
function2=function(a,b,c)a+b+c

do.call("function1",list(1,2))
do.call("function2",list(1,2,3))

РЕДАКТИРОВАТЬ: Обертка будет:

applyfunction=function(fun,...)do.call(fun,list(...))

applyfunction("function1",1,2)
applyfunction("function2",1,2,3)
6 голосов
/ 10 февраля 2011

Вот еще одна альтернатива.Вы можете добавить больше функций в список switch.

func1 <- function(a, b) a + b
func2 <- function(a, b) a - b
applyfunction <- function(FUN, arg1, arg2) {
  appFun <- switch(FUN,
      func1,  # FUN == 1
      func2,  # FUN == 2
      stop("function ", FUN, " not defined"))  # default
  appFun(arg1, arg2)
}
applyfunction(1,2,3)
# [1] 5
applyfunction(2,9,43)
# [1] -34
applyfunction(3,9,43)
# Error in applyfunction(3, 9, 43) : function 3 not defined
5 голосов
/ 10 февраля 2011

Если вы действительно хотите, чтобы это делалось «по числам»:

> applyfunction=function(n,a,b){get(paste("func",n,sep=""))(a,b)}
> func1=function(a,b){a+b}
> func2=function(a,b){a*b}
> applyfunction(1,4,3)
[1] 7
> applyfunction(2,4,3)
[1] 12

Использует get и paste для получения функции, связанной с именем.

0 голосов
/ 11 февраля 2011

Здесь альтернатива для переключения или вставки, просто используйте индексирование для выбора из списка:

 function1=function(a,b) a+b
 function2=function(a,b,c) a*b
 applyfunc <- function(n, aa, bb){ c(function1, function2)[[n]](aa,bb) }
 applyfunc(1, 4, 3)
 # [1] 7
 applyfunc(2, 4, 3)
 #[1] 12
 applyfunc(3, 4, 3)
# Error in c(function1, function2)[[n]] : subscript out of bounds
0 голосов
/ 10 февраля 2011

А как насчет использования одной из переменных функций в качестве переключателя?

func1 <- function(x,y,z) { 
## Function One stuff goes here
if (x == 1) { 
var1 <- 1 
} 
## Function Two stuff goes here 
if (x == 2) { 
var1 <- 2 
}
return(var1)
} 

И вы можете использовать ту же функцию, а переключатель - это переменная "x":

> func1(1,1,1)
[1] 1
> func1(2,1,1)
[1] 2
...