2015-06-22 43 views
4

的名單我有以下情況:複製data.tables

1)數據表

2)出於測試目的的名單我故意想(深)複製整個列表,包括數據表

3)我想從複製列表中取一些元素並添加一個新列。

下面是代碼:

library(data.table) 
x = data.table(aaa = c(1,2)) 
y = data.table(bbb = c(1,2)) 
z = list(x,y) 
zz = copy(z) 

v = zz[[1]] 
v = v[, newColumn := 1] 

現在即時得到以下錯誤:

Error in `[.data.table`(res, , `:=`(xxx, TRUE)) : 
(converted from warning) Invalid .internal.selfref detected and fixed 
by taking a copy of the whole table so that := can add this new column 
by reference. At an earlier point, this data.table has been copied by R 
(or been created manually using structure() or similar). Avoid key<-, 
names<- and attr<- which in R currently (and oddly) may copy the whole 
data.table. Use set* syntax instead to avoid copying: ?set, ?setnames 
and ?setattr. Also, in R<=v3.0.2, list(DT1,DT2) copied the entire DT1 
and DT2 (R's list() used to copy named objects); please upgrade to 
R>v3.0.2 if that is biting. If this message doesn't help, please report 
to datatable-help so the root cause can be fixed. 

我不明白的副本呼叫系統精確的用R處理的,它們是如何傳遞給數據。表,但不是這樣的:(?)

如果有人明確地使用複製功能,然後他/她意識到「按價值」和「按引用」之間存在差異的事實。所以他/她應該分發對象的真實副本。

因此,我認爲不應該有任何錯誤,我認爲這是一個錯誤發生的'錯誤'。那是對的嗎?

FW

+0

您使用的是哪種版本的'R'和'data.table'? –

回答

5

copy()是用於複製data.table的。您正在使用它來複制list。嘗試..

zz <- lapply(z,copy) 
zz[[1]][ , newColumn := 1 ] 

使用你原來的代碼,你會看到,申請copy()list不會使原有data.table的副本。它們仍被內存中的相同位置引用:

library(data.table) 
x = data.table(aaa = c(1,2)) 
y = data.table(bbb = c(1,2)) 
z = list(x,y) 
zz = copy(z) 

# Both zz$x and z$x are the same object: 
.Internal(inspect(zz$x)) 
# @7fd58a079778 00 NILSXP g1c0 [MARK,NAM(2)] 
.Internal(inspect(z$x)) 
# @7fd58a079778 00 NILSXP g1c0 [MARK,NAM(2)] 
+0

這是很好的答案,但我正在努力與你的*「'副本」是爲了複製'data.table's「*。其實你可以在任何* R對象(包括列表,例如'l < - list(1); l2 < - copy(l); .Internal(inspect(l)); .Internal(inspect (l2))'),這只是OP在這種特殊情況下沒有正確使用'data.table'。 –

+0

@DavidArenburg我也注意到了這一點,但僅僅因爲它*在其他對象上工作並不意味着它是*意圖*。如果是這種情況,那麼應該更新文檔,因爲它指出對於'copy(x)','x'是一個'data.table'。正如我所看到的那樣,'copy()'被定義並記錄在'data.tables'上以某種方式工作,其他任何事情都是用戶風險/錯誤。 –

+1

我認爲我們應該做一個PR然後修復文檔:) –