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):

ただし、ディスクからロードされたテーブルの場合、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 に答える