简体   繁体   中英

Passing all arguments to another function

I'd like to be able to pass current arguments in a function to another function without individually listing each of the arguments. This is for a slightly more complex function which will have about 15 arguments with potentially more arguments later added (it's based on an API for data which might have more complex data added later):

f_nested <- function(a, b, ...) {
  c <- a + b
  return(c)
}

f_main <- function(a, b) {

  d <- do.call(f_nested, as.list(match.call(expand.dots = FALSE)[-1]))

  c <- 2 / d

  return(c)
}

f_main(2, 3)
#> [1] 0.4

sapply(2:4, function(x) f_main(x, 4))
#> Error in (function (a, b, ...) : object 'x' not found

Created on 2019-06-28 by the reprex package (v0.3.0)

The first call to f_main(2, 3) produces the expected result. However, when iterating over a vector of values with sapply an error arises that the object was not found. I suspect my match.call() use is not correct and I'd like to be able to iterate over my function.

I'll borrow from lm 's used of match.call , replacing the first element with the next function. I think one key is to call eval with the parent.frame() , so that x will be resolved correctly.

# no change
f_nested <- function(a, b, ...) {
  c <- a + b
  return(c)
}
# changed, using `eval` instead of `do.call`, reassigning the function name
f_main <- function(a, b) {
  thiscall <- match.call(expand.dots = TRUE)
  thiscall[[1]] <- as.name("f_nested")
  d <- eval(thiscall, envir = parent.frame())
  c <- 2 / d
  return(c)
}
sapply(2:4, function(x) f_main(x, 4))
# [1] 0.3333333 0.2857143 0.2500000

As @MrFlick suggested, this can be shortened slightly with:

f_main <- function(a, b) {
  thiscall <- match.call(expand.dots = TRUE)
  thiscall[[1]] <- as.name("f_nested")
  d <- eval.parent(thiscall)
  c <- 2 / d
  return(c)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM