Pass function name as argument in mapply?

Viewed 158

I would like to pass a function name as an argument in mapply:

f2 <- function(a, b) a + b^2
f <- function(a, b, func) func(a, b)
f(1, 3, f2)  ## returns 10
mapply(f2,  1:2,  3)  ## returns [1] 10 11
mapply(function(a, b) f(a, b, f2), 1:2,  3) ## returns [1] 10 11
mapply(f,  1:2,  3,  f2)  ## fails

The final mapply call generates the error

Error in dots[[3L]][[1L]] : object of type 'closure' is not subsettable

Is there any way to do this?

2 Answers

mapply assumes you want to iterate over all the vectors you pass after the first function. But you want to use the same value of f2 for every iteration. You can do that useing the MoreArgs= parameter

mapply(f,  1:2,  3,  MoreArgs=list(func=f2))

You don't have the same problem with the 3 because R will perform vector recycling to expand 3 to c(3,3) to match the same length as c(1,2). Functions in R don't have the same implicit recycling behaviors. But if you want the value to always stay the same, it's better to put it in the MoreArgs parameter

1) Wrap the function in a list:

mapply(f,  1:2,  3,  list(f2))
## [1] 10 11

2) Typically functions that have function arguments use match.fun so that one can pass either the function or a character string containing its name. For example, mapply itself does that so the above line of code could equally be written as: mapply("f", 1:2, 3, list(f2)) . If f were written that way then we could simply specify the name of f2 as a character string, namely "f2" .

f <- function(a, b, func) {
  func <- match.fun(func)
  func(a, b)
}

mapply(f,  1:2,  3,  "f2")
## [1] 10 11
Related