2011-02-10 7 views
8

Questa è una domanda riguardante la codifica in R.R: specifica una stringa come argomento di una funzione che chiama un'altra funzione

L'esempio che fornisco è didattico. Supponiamo che abbia funzioni chiamate 'func1' e 'func2', dove ognuno prende due argomenti (diciamo scalari). Voglio specificare un'altra funzione 'applyfunction' che ha tre arg: l'ultimo numero della funzione da usare ('1' o '2'), e i due argomenti per la funzione. Per esempio, io voglio fare qualcosa di simile (che ovviamente non funziona):

applyfunction(1,2,3) dove sarebbe effettivamente dirette func1(2,3) e

applyfunction(2,9,43) dove sarebbe effettivamente dirette func2(9,43).

Qualche idea?

migliore, DB

risposta

7

Si potrebbe desiderare di guardare do.call(), che chiama una funzione con argomenti forniti in un elenco. Non è difficile scrivere intorno a questo un wrapper che faccia esattamente quello che vuoi.

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: Un wrapper potrebbe essere:

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

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

Ecco un'altra alternativa. È possibile aggiungere più funzioni all'elenco 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

Se si vuole veramente farlo fare 'dai numeri':

> 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 

utilizza GET e incolla per ottenere la funzione associata a un nome.

+0

'match.fun' è leggermente preferibile a' get' per questo utilizzo. – hadley

+0

@hadley: perché? Non sarebbe 'match.fun' basta chiamare' get' con 'envir' e' mode' args in questo caso? –

+0

Controlla anche che l'oggetto trovato sia una funzione ... – hadley

0

Che ne è dell'utilizzo di una delle variabili di funzioni come interruttore?

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

E, si arriva a usare la stessa funzione, con l'opzione di essere la variabile "x":

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

Qui un supplente per cambiare o di pasta, basta usare l'indicizzazione per selezionare da un elenco :

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