13
votes

I've a function f() that has some named parameters. It calls a function g() and I want to pass all f's parameters to it. Is this possible?

Using ... just covers the extra arguments:

f=function(a,callback,b,c,d,...){
  z=a-b
  callback(z,...) 
  }

g=function(z,...){
  print(list(...))    #Only shows $e
  print(z)    #-1
  print(a,b,c,d)  #'a' not found   
}

f(1,g,2,3,d=4,e=5);

I thought formals() was the answer, but it just seems to be argument names, not their values!

f=function(a,callback,b,c,d,...){
  z=a-b
  callback(z,formals()) 
  }

g=function(z,...){
  args=list(...)[[1]]
  print(args$a) #(no output)
  print(class(args$a))  #"name"
}

f(1,g,2,3,d=4,e=5);

Is it possible? Thanks.

1
Have a look at the code for lm and glm to see how this is done. - Hong Ooi
@HongOoi Thanks; it is done with match.call (i.e. just like Anton's answer), though IIUC it chooses to only pass on certain args, not all of them. - Darren Cook

1 Answers

16
votes

Well, something like this is certainly possible. You should just figure our for yourself in which frame / point you'd like to evaluate the arguments of f which are then forwarded to g.

The typical procedure consists of match.call() call inside f to actually record the call expression which f was called with, then changing the call expression as it should be convenient for you (e.g. filtering out unnecessary args, adding new, etc.) and then evaluation of the new call expression via eval() call. So, something like this should (almost) work:

f <- function(a, callback, b, c, d, ...) {
  # Grab the "f" call expression
  fcall <- match.call(expand.dots = FALSE)

  # Construct the new call expression
  fcall[[1]] <- callback
  # Filter out / add new args
  fcall$callback <- NULL
  fcall$z <- z

  # Do the call
  eval(fcall, parent.frame())
}