【问题标题】:Passing all arguments to another function将所有参数传递给另一个函数
【发布时间】:2019-06-28 17:32:23
【问题描述】:

我希望能够将一个函数中的当前参数传递给另一个函数,而无需单独列出每个参数。这是一个稍微复杂一点的函数,它有大约 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 package (v0.3.0) 于 2019 年 6 月 28 日创建

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

【问题讨论】:

  • 也许将其作为列表的一个参数...f(a=mylist); mylist=list(a=1, b=2, c=3, ...)
  • 现在我想得更多,这就是我过去的做法... API 配置文件在单独的文件或环境变量中,将其读入列表,将列表传递给函数调用 API。

标签: r


【解决方案1】:

我将借用 lmmatch.call 的使用,将第一个元素替换为下一个函数。我认为一个关键是用parent.frame()调用eval,这样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)
}

【讨论】:

  • 有一个eval.parent() 是一个很好的捷径
  • 如果它有一个自动替换函数名的选项(如eval.parent(thiscall, newfunc = "f_nested")),它会是一个更好的简写,但我只是懒惰。 :-)
猜你喜欢
  • 2011-03-09
  • 2012-09-25
  • 2020-10-03
  • 2012-04-18
  • 2014-01-06
  • 2019-10-09
  • 1970-01-01
相关资源
最近更新 更多