首页 > 解决方案 > 传递所有参数

问题描述

考虑以下:

foo <- function(a = 1, b = 2, c = 3, d = 1, e = 2, f = 3, g = 4, h = 1) {
    print(h)
    bar(a = a, b = b, c = c, d = d, e = e, f = f, g = g)
    foobar(c = c, e = e, g = g)
}

bar <- function(a, b, c, d, e, f, g) {
    a + b + c + d + e + f * g
}

foobar <- function(c, e, g) {
    if (c) {
         print(g +  e)
    }
}

foo(1, 2, 3, 4,5, 6, 7, 8)

我有与上面类似的东西,其中我有子函数调用,这些调用需要从它上面的级别传递下来的大量变量。是否有更简单的方法来执行此代码的第 3 行和第 4 行,而不是每次调用它时手动列出每个变量?

标签: r

解决方案


好吧,我们可以创建一个辅助函数来使这更容易

call_match_args <- function(fun, data) {
  fun <- match.fun(fun)
  seeking <- names(formals(fun))
  stopifnot(all(seeking %in% names(data)))
  do.call(fun, data[seeking], envir=parent.frame())
}

这将接受一个函数和一个列表,并将列表中与函数参数名称匹配的所有值作为参数传递。该do.call函数负责将列表转换为参数。

然后我们可以改变你的foo功能看起来像这样

foo <- function(a = 1, b = 2, c = 3, d = 1, e = 2, f = 3, g = 4, h = 1) {
  vars <- mget(ls())
  print(vars$h)
  call_match_args(bar, vars)
  call_match_args(foobar, vars)
}

foo(1, 2, 3, 4,5, 6, 7, 8)
# [1] 8
# [1] 12

whilebarfoobar可以保持不变。该函数的第一步是获取所有参数值并将它们放在一个列表中。然后您从该列表访问它们并将该列表传递给call_match_args辅助函数。


推荐阅读