我在R中有一个函数,它应该通过向它添加新项来修改列表。但是我真的不想复制我的清单。
我知道在R中这不是一个简单的任务,我已经看到了一些使用eval.parent函数的最小例子,但我不知道它们将如何应用于我的特定情况。
我的问题(不是我的实际功能)的最小例子看起来像
L <- list(o1 = 1, o2 = 2, o3 = 3)
add_to_list <- function(L){
n1 <- sum(unlist(L))
n2 <- mean(unlist(L))
L$n1 <- n1
L$n2 <- n2
return(L)
}
L <- add_to_list(L)
如果我是正确的,因为L被修改,函数add_to_list将生成L的完整副本,包括o1,o2和o3,在这个例子中? (当我查看我的实际功能的计算时间时,它似乎是这样。)
我想通过引用传递L,因为这会大大提高我的代码的性能。在我的实例中,有超过三个对象o1,o2和o3,其中一些非常大,在最终赋值之前我也有很多代码,这就是为什么我希望它模块化为函数。
实际上,我认为附加到列表并不会对前面的元素进行深层复制,您可以使用基R来测试它:
x <- 1:2
tracemem(x)
y <- 3:4
L <- list(x=x, y=y)
foo <- function(L) {
L$z <- 5:6
L
}
# no copy shown here
L <- foo(L)
# copy shown, x copied so that L$x stays unmodified
x[1L] <- 0L
或者与pryr
:
library(pryr)
x <- 1:2
address(x)
[1] "0x26f5f344ba0"
foo <- function(L) {
L$z <- 5:6
L
}
L <- list(x=x)
L <- foo(L)
lx <- L$x
address(lx)
[1] "0x26f5f344ba0"