R: specifying a string as an argument of a function that calls another function
Asked Answered
O

5

8

This is a question regarding coding in R.

The example I provide is didactic. Suppose I have functions called 'func1' and 'func2', where each takes two arguments (let's say scalars). I want to specify another function 'applyfunction' that has three args: the last number of the function to use ('1' or '2'), and the two arguments for the function. For example, I want to do something like this (which of course doesn't work):

applyfunction(1,2,3) where it would effectively run func1(2,3) and

applyfunction(2,9,43) where it would effectively run func2(9,43).

Any ideas?

Best, DB

Ody answered 10/2, 2011 at 16:31 Comment(0)
A
7

You might want to look at do.call(), which calls a function with arguments supplied in a list. It is not to hard to write a wrapper around this that does exactly what you want.

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: A wrapper would be:

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

applyfunction("function1",1,2)
applyfunction("function2",1,2,3)
Ain answered 10/2, 2011 at 16:58 Comment(0)
E
6

Here's another alternative. You can add more functions to the switch list.

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
Empoverish answered 10/2, 2011 at 17:15 Comment(0)
D
5

If you really want it done 'by the numbers':

> 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

Uses get and paste to get the function associated with a name.

Dropforge answered 10/2, 2011 at 17:34 Comment(4)
match.fun is slightly preferable to get for this use.Creosote
@hadley: Why? Wouldn't match.fun just call get with envir and mode args in this case?Empoverish
To expand, yes you're right, but the answer didn't do that and the name is more evocativeCreosote
@hadley: Thanks, just wanted to make sure I understood.Empoverish
P
0

What about using one of the functions variables as a switch?

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

And, you get to use the same function, with the switch being the variable "x":

> func1(1,1,1)
[1] 1
> func1(2,1,1)
[1] 2
Paschall answered 10/2, 2011 at 20:3 Comment(0)
R
0

Here an alternate to switch or paste, just use indexing to select from a list:

 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
Runny answered 10/2, 2011 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.