我在R中开发一个包,主要接口是两个类:一个处理数据的类(让我们称之为Data)和一个处理Data实例集合的类(我们称之为Collection)。数据实例可能相当大(50 mb +),这就是Collection类是环境包装的原因。
我想为Data实现一个c()
函数,这将导致一个Collection实例。为了做到这一点,参数将作为...
传递,并且必须迭代地构建Collection实例。我知道我可以首先通过...
将其列为一个列表来遍历list(...)
,但这可能会非常昂贵。无论如何在没有先将所有内容复制到临时列表的情况下循环遍历...
?
答案 0 :(得分:2)
似乎有用的是使用pryr package中的dots
函数(我可以想象还有其他更简单的解决方案):
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
}
使用list
和不带...
的实现
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
我们发现使用dots
的实现与没有...
的实现类似,并且比使用list
的实现更快。
如果您不想依赖pryr
:dots
的代码非常“简单”:
dots <- function (...) {
eval(substitute(alist(...)))
}