首页 > 解决方案 > 将所有参数传递给另一个函数

问题描述

我希望能够将函数中的当前参数传递给另一个函数,而无需单独列出每个参数。这是一个稍微复杂一点的函数,它将有大约 15 个参数,稍后可能会添加更多参数(它基于数据 API,稍后可能会添加更复杂的数据):

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

reprex 包(v0.3.0)于 2019 年 6 月 28 日创建

第一次调用 f_main(2, 3) 会产生预期的结果。但是,当迭代带有sapply错误的值向量时,会出现找不到对象的错误。我怀疑我的match.call()使用不正确,我希望能够迭代我的函数。

标签: r

解决方案


我将借用lm's used of match.call,用下一个函数替换第一个元素。我认为一个关键是用 调用evalparent.frame()这样x就可以正确解决。

# 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

正如@MrFlick 建议的那样,这可以通过以下方式稍微缩短:

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)
}

推荐阅读