2011-02-10 3 views
8

Ceci est une question concernant le codage dans R.R: spécification d'une chaîne comme argument d'une fonction qui appelle une autre fonction

L'exemple que je donne est didactique. Supposons que j'ai des fonctions appelées 'func1' et 'func2', où chacune prend deux arguments (disons des scalaires). Je veux spécifier une autre fonction 'applyfunction' qui a trois arguments: le dernier numéro de la fonction à utiliser ('1' ou '2'), et les deux arguments pour la fonction. Par exemple, je veux faire quelque chose comme ça (ce qui bien sûr ne fonctionne pas):

applyfunction(1,2,3) où il serait effectivement courir func1(2,3) et

applyfunction(2,9,43) où il courrait effectivement func2(9,43).

Des idées?

Best, DB

Répondre

7

Vous voudrez peut-être regarder do.call(), qui appelle une fonction avec des arguments fournis dans une liste. Il n'est pas difficile d'écrire un emballage autour de ce qui fait exactement ce que vous voulez.

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 emballage serait:

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

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

Voici une autre alternative. Vous pouvez ajouter plus de fonctions à la liste 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 vous voulez vraiment faire « par les chiffres »:

> 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 

obtenir et coller Utilise pour obtenir la fonction associée à un nom. Qu'en est-il de l'utilisation de l'une des variables de fonctions comme commutateur?

+0

'match.fun' est légèrement préférable à' get' pour cette utilisation. – hadley

+0

@hadley: Pourquoi? Est-ce que 'match.fun' n'appellerait pas' get' avec les arguments 'envir' et' mode' dans ce cas? –

+0

Il vérifie également que l'objet trouvé est une fonction ... – hadley

0

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

Et, vous aurez à utiliser la même fonction, avec le commutateur étant la variable « x »:

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

Voici un autre pour changer ou de pâte, il suffit d'utiliser l'indexation pour sélectionner dans une liste :

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 
Questions connexes