Reduce() 和 ...(省略号)

Reduce() and ... (ellipsis)

Hadley's advice in Advanced R 之后,我正在尝试使用 Reduce() 创建合并函数的递归版本。然而,他的例子使用了一个数字向量,例如

Reduce(`+`, 1:3)
[1] 6

而我希望能够使用 ...(省略号)给出多个参数。我的想法是这样的:

merge_datasets_multi = function(..., main=1, time=F) {
  #wrap with Reduce
  Reduce(function(x, y) merge_datasets(x, y, main=main, time=time), ...)

  #debugging, verify that the anonymous function works
  #(function(x, y) merge_datasets(x, y, main=main, time=time))(iris[1:50, ], iris[51:100, ])
}

merge_datasets()函数在my personal package.

我已经测试了我创建的匿名函数在给定两个参数时是否有效。

但是,这会引发错误:

merge_datasets_multi(iris[1:50, ], iris[51:100, ], iris[101:150, ])
Error in if (right) { : argument is not interpretable as logical
In addition: Warning message:
In if (right) { :
  the condition has length > 1 and only the first element will be used
Called from: Reduce(function(x, y) merge_datasets(x, y, main = main, time = time), 
    ...)

大概是因为第三个参数 (a data.frame) 被传递给了一个条件语句,它无法计算为 true 或 false 并抛出错误。

因此,如果我们改为给它一个 data.frameslist,它应该可以工作:

merge_datasets_multi(list(iris[1:50, ], iris[51:100, ], iris[101:150, ]))

确实如此。但是,这需要用户在调用 merge_datasets_multi().

之前将 data.frames 添加到 list 中的额外步骤

我尝试将 as.list(...) 作为参数传递给 Reduce(),但它不起作用。输出只是第一个 data.frame 转换为 list.

如何用 Reduce() 创建一个以 ... 作为输入的顺序函数?

答案显然很简单。与其尝试 as.list(),不如使用 list()。参见 this previous answer

library(magrittr)
merge_datasets_multi = function(..., main=1, time=F) {
  #wrap with Reduce
  Reduce(function(x, y) merge_datasets(x, y, main=main, time=time), list(...))
}
merge_datasets_multi(iris[1:50, ], iris[51:100, ], iris[101:150, ]) %>% dim
[1] 150   5