Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R - Call a function from function name that is stored in a variable?

Tags:

r

I'm writing some R code and I want to store a list of Function names and what they are for in a dataframe, and then query that dataframe to determine which function to call, but I can't figure out how to do this, or if it's even possible.

As a basic example, let's assume the function name is just stored as a string in a variable, how do I call the function based on the function name stored in that variable?

MyFunc <-function() {
    # Do some stuff...
    print("My Function has been called!!!")
    return(object)
}

FuncName <- "MyFunc()"
Result <- FuncName

I need to make

Result <- FuncName

Work the same as

Result <- MyFunc()

Also, passing objects, or other variables, to the functions is not a concern for what I am doing here, so those () will always be empty. I realize passing variables like this might get even more complicated.

like image 972
user3246693 Avatar asked Nov 13 '15 22:11

user3246693


2 Answers

You could use get() with an additional pair of ().

a<-function(){1+1}                                                                                                  
var<-"a"

> get(var)()
[1] 2
like image 74
Alex Avatar answered Oct 17 '22 19:10

Alex


To get a function from its name, try match.fun, used just like get in the answer provided by @Alex:

> a <- function(x) x+1
> f <- "a"
> match.fun(f)(1:3)
[1] 2 3 4

To call a function directly using its name, try do.call:

> params <- list(x=1:3)
> do.call(f, params)
[1] 2 3 4

The advantage to do.call is that the parameters passed to the function can change during execution (e.g., values of the parameter list can be dynamic at run time or passed by the user to a custom function), rather than being hardwired in the code.

Why do I suggest match.fun or do.call over get? Both match.fun and do.call will make sure that the character vector ("a" in the above examples) matches a function rather than another type of object (e.g., a numeric, a data.frame, ...).

Consider the following:

# works fine
> get("c")(1,2,3)
[1] 1 2 3

# create another object called "c"
> c <- 33
> get("c")
[1] 33

#uh oh!!
> get("c")(1,2,3)
Error: attempt to apply non-function

# match.fun will return a function; it ignores
# any object named "c" that is not a function.
> match.fun("c")(1,2,3)
[1] 1 2 3

# same with do.call
> do.call("c", list(1,2,3))
[1] 1 2 3
like image 25
Geoffrey Poole Avatar answered Oct 17 '22 20:10

Geoffrey Poole