I'm developing a package in R which main interface is two classes: a class handling data (let's call it Data) and a class handling a collection of Data instances (we call it Collection). Data instances can be rather larger (50 mb +), which is why the Collection class is a wrapper around an environment.
I want to implement a c()
function for Data which will result in a Collection instance. In order to do so the arguments are passed as ...
and the Collection instance has to be build up iteratively. I know I can loop through ...
by first making it a list by list(...)
, but this could be potentially expensive. Is there anyway to loop through ...
without first copying everything over to a temporary list?
What seems to work is to use the dots
function from the pryr package (I can imagine there are other more simple solutions possible):
library(pryr)
fun1 <- function(...) {
l <- dots(...)
result <- list(mode="list", length = length(l))
for (i in seq_along(l)) {
v <- l[[i]]
result[[i]] <- eval(v)
}
result
}
Timing this against an implementation using list
and an implementation without ...
fun2 <- function(...) {
l <- list(...)
result <- list(mode="list", length = length(l))
for (i in seq_along(l)) {
v <- l[[i]]
result[[i]] <- v
}
result
}
fun1 <- function(...) {
l <- dots(...)
result <- list(mode="list", length = length(l))
for (i in seq_along(l)) {
v <- l[[i]]
result[[i]] <- eval(v)
}
result
}
fun3 <- function(a, b) {
list(a, b)
}
> system.time(r1 <- fun1(large_object1, large_object2))
user system elapsed
0.060 0.072 0.133
> system.time(r2 <- fun2(large_object1, large_object2))
user system elapsed
0.132 0.132 0.265
> system.time(r3 <- fun3(large_object1, large_object2))
user system elapsed
0.056 0.076 0.132
We see that the implementation using dots
performs similar as the implementation without ...
and faster than the implementation using list
.
If you don't want to depend on pryr
: the code of dots
is quite 'simple':
dots <- function (...) {
eval(substitute(alist(...)))
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments