2011-02-10 17 views
8

Esta es una pregunta sobre la codificación en R.R: especificando una cadena como argumento de una función que llama a otra función

El ejemplo que proporciono es didáctico. Supongamos que tengo funciones llamadas 'func1' y 'func2', donde cada una toma dos argumentos (digamos escalares). Quiero especificar otra función 'aplicar función' que tenga tres argumentos: el último número de la función a usar ('1' o '2') y los dos argumentos para la función. Por ejemplo, quiero hacer algo como esto (que por supuesto no funciona):

applyfunction(1,2,3) donde podría funcionar con eficacia y func1(2,3)

applyfunction(2,9,43) donde podría ejecutar con eficacia func2(9,43).

¿Alguna idea?

mejor, DB

Respuesta

7

Es posible que desee ver en do.call(), que llama a una función con argumentos proporcionados en una lista. No es difícil escribir un envoltorio alrededor de esto que haga exactamente lo que quieras.

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)) 

EDIT: Una envoltura sería:

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

applyfunction("function1",1,2) 
applyfunction("function2",1,2,3) 
6

Aquí hay otra alternativa. Puede agregar más funciones a la lista 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

Si realmente quiere que se haga 'por los números':

> 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 

utiliza GET y pegar para obtener la función asociada a un nombre.

+0

'match.fun' es ligeramente preferible a' obtener' para este uso. – hadley

+0

@hadley: ¿Por qué? ¿No sería 'match.fun' simplemente llamar' get' con 'envir' y' mode' args en este caso? –

+0

También comprueba que el objeto encontrado sea una función ... – hadley

0

¿Qué hay de usar una de las variables de funciones como un interruptor?

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) 
} 

Y, se llega a utilizar la misma función, con el interruptor siendo la variable "x":

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

Aquí un suplente para cambiar o pasta, sólo tiene que utilizar la indexación para seleccionar de una lista :

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 
Cuestiones relacionadas