将对象列为具有可覆盖列表元素默认值的函数参数

List objects as function arguments with overridable list element defaults

我有一个 R 函数,它接受大量参数 (18),我想将这些参数作为列表传入。当我手动 运行 宁这个功能时,可以这么说,我通常想使用所有的默认值,但一两个,但我也想 运行 这个相同的功能多次与各种组合默认和非默认项目,我想以编程方式 assemble 作为列表。

我知道我可以将 18 个以上的参数作为单独的形式化,然后 assemble 将它们放入函数内的列表中,但我希望我可以将列表作为形式化的默认值,并且然后让元素也有默认值。像这样:

> f <<- function(x, y = list(a=0, b=3)) {with(y, (x + a + b))}
> f(1)
[1] 4
> f(x=1, y$a = 1)
Error: unexpected '=' in "f(x=1, y$a ="

(或者)

In y$a <- 1 :
 Error in eval(substitute(expr), data, enclos = parent.frame()) : 
  object 'a' not found 

除了输出 5 而不是错误。我怀疑没有办法做到这一点,因为 R 无法将列表中的赋值识别为创建默认值,而只能识别为创建命名元素。但也许用正式的分配形式?或者通过巧妙地使用 do.call?

这里有一些备选方案:

1) modifyList 使用modifyList处理默认值。

f1 <- function(x, y = list()) {
  defaults <- list(a = 0, b = 3)
  with(modifyList(defaults, y), {
    x + a + b
  })
}

f1(x = 1)
## [1] 4
f1(x = 1, y = list(a = 1))
## [1] 5

2) do.call 另一种可能是有两个函数。第一个不使用列表,第二个(用户调用的列表)使用 do.call 来调用第一个。

f2impl <- function(x, a = 0, b = 3) x + a + b
f2 <- function(x, y = list()) do.call("f2impl", c(x, y))

f2(x = 1)
## [1] 4
f2(x = 1, y = list(a = 1))
## [1] 5