3

似乎如果 adata.table是新加载的,则包含的函数:=不会通过引用进行修改。

任何人都可以复制它吗?它是一个错误吗?

test<-function(data){data[,ppp:=1]}

a<-data.table(x=1:2)
save(a,file="ttt")
load("ttt")
test(a) # show ppp
a # doesn't have ppp


b<-data.table(x=1:2)
test(b) # show ppp
b # has ppp

更新

如果列指针向量中没有剩余插槽,则将执行浅拷贝,这是一种“特征”。data.table名称绑定到新向量。它在同一范围内工作正常。但是,除非手动将返回值绑定到名称,否则外部范围无法看到此更改。

options(datatable.alloccol=4)
options(datatable.verbose=TRUE)
a<-as.data.table(matrix(1:20, ncol=4))
truelength(a) # 4
test<-function(x){print(truelength(x));x[,pp:=1];print(truelength(x));x}
test(a)
a # doesn't change
4

1 回答 1

5

需要在内存中过度分配 data.table 以通过引用工作来添加列。加载后情况并非如此:

load("ttt")
length(a)
#[1] 1
truelength(a)
#[1] 0

b <- data.table(x=1:2)
length(b)
#[1] 1
truelength(b)
#[1] 100

来自help(truelength)

然而,对于从磁盘加载的表,真实长度在 R 2.14.0 中为 0,在 R <= 2.13.2 中为随机;即,在这两种情况下都可能出乎意料。data.table 检测到此状态,并在发生下一列添加或删除时过度分配加载的 data.table。

但是,如果您将(新加载的)data.table 传递给函数,然后在函数内部通过引用添加,就会发生过度分配,但不会在全局环境中到达符号(只有函数内部的局部符号) )。如果您直接在全局环境中执行此操作,或者不将 data.table 作为函数参数传递,则它可以工作。

如果 data.table 已经被过度分配(通常情况下,除了从磁盘新加载时),则有备用插槽供列通过引用添加,并且没有浅拷贝(以实现过度分配) 需要:=在函数内部完成。

这可能值得一个错误报告(但我还没有检查是否已经有一个)。

R version 3.0.1 (2013-05-16)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

locale:
[1] de_DE.UTF-8/de_DE.UTF-8/de_DE.UTF-8/C/de_DE.UTF-8/de_DE.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] microbenchmark_1.3-0 data.table_1.8.8    

loaded via a namespace (and not attached):
[1] tools_3.0.1
于 2013-08-28T17:33:12.293 回答