Palace Chan
Palace Chan

Reputation: 9183

How to call a function in R which I specify via the commandline?

How do I do this in R:

I have sourced a function with some name exampleFoo suppose:

exampleFoo <- function(a, predefined, signature)

Given the character vector exampleFoo, how can I use that to call the function with that name?

Upvotes: 0

Views: 82

Answers (3)

Gavin Simpson
Gavin Simpson

Reputation: 174778

It depends if this is going on inside another function or at the top level. I'll take those in reverse order.

exampleFoo <- function(a, predefined, signature) {
   1:10
}

FUN <- "exampleFoo"

get(FUN)
get(FUN)()

> get(FUN)
function(a, predefined, signature) {
   1:10
}
> get(FUN)()
 [1]  1  2  3  4  5  6  7  8  9 10

In a function, the match.fun argument is most applicable here. get looks for objects with the name supplied to it, whereas match.fun only considers function objects when searching. This has the additional benefit then of not matching non-function objects that may have the same name.

FOO <- function(f) {
  BAR <- match.fun(f)
  BAR()
}

> FOO(FUN)
 [1]  1  2  3  4  5  6  7  8  9 10
> FOO("exampleFoo")
 [1]  1  2  3  4  5  6  7  8  9 10

You can't use match.fun (easily?) at the top level as it is designed to perform matching in the parent frame of the caller and the Global environment doesn't have a parent (IIRC).

Other Examples

@agstudy suggests a switch based approach to having a wrapper function that can call one of several pre-defined functions by name. In the comments there I proposed two simpler alternatives. Here I expand upon that:

foo1 <- function(method, ...) {
  dots <- list(...)
  FUN <- match.fun(method)
  do.call(FUN, dots)
} 

or

foo2 <- function(method = c("fun1", "fun2", "fun3"), ...) {
  dots <- list(...)
  method <- match.arg(method)
  FUN <- match.fun(method)
  do.call(FUN, dots)
}

I've written these as pretty general functions which take any arguments plus method. If the functions reference by / passed to method have a ... argument, then these could be called directly, perhaps with one or more named arguments, e.g.

## assuming `method` refers to a function with a first argument `x` and also
##   a `...` argument
foo3 <- function(method, x, ...) {
  FUN <- match.fun(method)
  FUN(x, ...)
}

Upvotes: 4

ndoogan
ndoogan

Reputation: 1925

text<-"exampleFoo"
exampleFoo<-function(x) print("Success")
eval(parse(text=paste(text,"()")))
#[1] "Success" 

As @joran suggested, get() seems to work as a replacement for eval(parse(text="..."))

get(text)()
#[1] "Success"

Upvotes: 1

agstudy
agstudy

Reputation: 121568

I would use switch for this, something like :

algoFactory <- function (method = c("algo1", "alog2", 
                                   "algo3")
{
  method = method[1]
  switch(method, algo1 = {
  res = algo1.Impl(...)
}, algo2 = {
  res = algo2.Impl(...)
}, algo3 = {
  res = algo3.Impl(...)
})}

And each time I add a new algorithm I update this main function. In your RscripT , you call it for example:

 Rscript  algoFactory.R 'algo1'

Upvotes: 1

Related Questions