我正在创建一个使用
我已经构建了一个简单的包来演示我的问题。
当我安装这个包时,我的理解是
如果我使用更加
如果我在函数内使用
data.table
作为数据集并具有一些使用 :=
进行引用分配的函数的包。我已经构建了一个简单的包来演示我的问题。
library(devtools)
install_github('foo','mnel')
它包含两个函数
foo <- function(x){
x[, a := 1]
}
fooCall <- function(x){
eval(substitute(x[, a :=1]),parent.frame(1))
}
以及一个数据集(非懒加载)DT
,使用以下方式创建
DT <- data.table(b = 1:5)
save(DT, file = 'data/DT.rda')
当我安装这个包时,我的理解是
foo(DT)
应该在DT
内赋值。 library(foo)
data(DT)
foo(DT)
b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
# However this has not assigned by reference within `DT`
DT
b
1: 1
2: 2
3: 3
4: 4
5: 5
如果我使用更加
正确
的方式tracmem(DT)
DT <- foo(DT)
# This works without copying
DT
b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
untracemem(DT)
如果我在函数内使用
eval
和substitute
fooCall(DT)
b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
# it does assign by reference
DT
b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
我应该坚持使用
DT <- foo(DT)
或者eval
/substitute
路线,或者- 我是否对
data
如何加载数据集的方式有所误解,即使不是懒惰加载?
DT
并不意味着它通过引用被赋值了,对吗?DT 可能已经被复制到.GlobalEnv
中,并且那可能是更新了它的地方。 - Matt Dowletracemem
会报告R本身的重复。这个函数很难捕捉到data.table的复制操作,例如当第一次进行过度分配时,因为从技术上讲,那不是完全的复制,而是一种过度分配(虽然只是浅层的复制而非深层的)。 - Matt Dowlealloc.col
,看看会发生什么。 - Matt Dowlelibrary(foo); data(DT); alloc.col(DT); foo(DT)
可以按要求工作。 - mnel