Following Hadley's advice in Advanced R, I'm trying to create a recursive version of a merger function using Reduce()
. However, his example uses a vector of numbers, e.g.
Reduce(`+`, 1:3)
[1] 6
Whereas I want to be able to give multiple argument using ... (ellipsis). What I have in mind is something like this:
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, ])
}
The merge_datasets()
function is in my personal package.
I have tested that the anonymous function I make works when given two arguments.
However, this throws an error:
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),
...)
Presumably this is because the third argument (a data.frame
) gets passed to a conditional, which fails to evaluate to true or false and throws the error.
Thus, if we instead give it a list
of data.frames
, it should work:
merge_datasets_multi(list(iris[1:50, ], iris[51:100, ], iris[101:150, ]))
And it does. However, this requires the extra step for the user of adding the data.frames into a list
before calling merge_datasets_multi()
.
I tried passing as.list(...)
as the argument to Reduce()
, but it doesn't work. The output is just the first data.frame
converted to a list
.
How does one make a sequential function with Reduce()
that takes ...
as input?
The answer is apparently simple. Instead of trying as.list()
, one should just use list()
. See 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