1

I would like to use different functions as function arguments in R where the arguments of the function arguments might be different. I have seen this post which describes the case where one can use different function arguments with the same argument for each function. Here is an example of what I would like:

f <- function(func, x, y) {
  return(func(x, y))
}

func1 <- function(x) {
  return(x^2)
}

func2 <- function(x, y) {
  return(x*y)
}

f(func1, 2) # not working: Error in func(x, y) : unused argument (y)
f(func1, 2, 3) # not working Error in func(x, y) : unused argument (y)
f(func2, 2, 3) # works

What I would like to be able to do is include a range of arguments (i.e. x, y etc. above) for f but, when writing the function to use as function argument (e.g. func1 and func2), not have to include all arguments in that function. i.e. I want to be able to write func1(x) but not have include y as an argument. Setting default parameters does not help and I seem to not be able to use ... in the right way either.

Fatm
  • 67
  • 7

1 Answers1

4

Since you have differing arguments, I believe if you replace the inputs with ... may help:

f <- function(func, ...) {
  func <- match.fun(func) # Rui Barradas's comment to avoid matching with other objects
  return(func(...))
}
func1 <- function(x, ...) {
  return(x^2)
}

func2 <- function(x, y) {
  return(x*y)
}

f(func1, 2) 
f(func1, 2, 3) 
f(func2, x = 2, y = 3)

Output:

# > f(func1, 2) 
# [1]  4
# > f(func1, 2, 3) 
# [1] 4
# > f(func2, x = 2, y = 3)
# [1] 6
jpsmith
  • 11,023
  • 5
  • 15
  • 36
  • Almost but not quite. I think `func1` should be able to accept specific arguments too. – Fatm May 26 '22 at 12:09
  • This `func1` output is wrong, how can the square of a length 1 vector be length 69? And I'm getting `Error in x^2 : non-numeric argument to binary operator` as output of `f(func1, 2)`. The definition should be `func1 <- function(x, ...)` so that `func1` knows what `x` is. – Rui Barradas May 26 '22 at 12:09
  • Yes. You are suggesting that every function argument has `...` as an argument. – Fatm May 26 '22 at 12:14
  • 2
    Also, in order to avoid matching the function with other objects of the same name, include `func <- match.fun(func)` as the first line of `f`. – Rui Barradas May 26 '22 at 12:15
  • Great - I have edited to include this (please check I added it correctly). Thanks both for improving the answer – jpsmith May 26 '22 at 12:27
  • @RuiBarradas. Suppose I do: `g <- function(funca, funcb, ...) { funca <- match.fun(funca(...)) funcb <- match.fun(funcb(...)) return(c(funca(...), funcb(...))) }`. I get: `Error in match.fun(funca(...)) : 'func1(2, 3)' is not a function, character or symbol`. But if I don't use `match.fun` there is no error. – Fatm May 30 '22 at 09:14