data.table 1.8.1。:“DT1 = DT2”与DT1 = copy(DT2)不一样?

时间:2012-06-25 15:27:54

标签: r data.table

在使用不同的赋值运算符时,我注意到data.table中存在一些不一致(与我不一致)的行为。我不得不承认我从来没有完全区分“=”和copy(),所以也许我们可以在这里阐明一些。如果您使用“=”或“< - ”而不是下面的copy(),则在更改复制的data.table时,原始data.table也会更改。

请执行以下命令,您将看到我的意思

library(data.table)
example(data.table)

DT
   x y  v
1: a 1 42
2: a 3 42
3: a 6 42
4: b 1  4
5: b 3  5
6: b 6  6
7: c 1  7
8: c 3  8
9: c 6  9

DT2 = DT

现在我将更改DT2的v列:

DT2[ ,v:=3L]
   x y  v
1: a 1  3
2: a 3  3
3: a 6  3
4: b 1  3
5: b 3  3
6: b 6  3
7: c 1  3
8: c 3  3
9: c 6  3

但看看DT发生了什么:

DT
   x y  v
1: a 1  3
2: a 3  3
3: a 6  3
4: b 1  3
5: b 3  3
6: b 6  3
7: c 1  3
8: c 3  3
9: c 6  3
它也发生了变化。 所以:改变DT2改变了原来的DT。不是这样,如果我使用copy():

example(data.table)  # reset DT
DT3 <- copy(DT)
DT3[, v:= 3L]
   x y  v
1: a 1  3
2: a 3  3
3: a 6  3
4: b 1  3
5: b 3  3
6: b 6  3
7: c 1  3
8: c 3  3
9: c 6  3

DT
   x y  v
1: a 1 42
2: a 3 42
3: a 6 42
4: b 1  4
5: b 3  5
6: b 6  6
7: c 1  7
8: c 3  8
9: c 6  9

预计会出现这种情况吗?

1 个答案:

答案 0 :(得分:10)

是。这是预期的行为,并有详细记录。

由于data.table使用对原始对象的引用来实现就地修改,因此它非常快。

因此,如果确实想要复制数据,则需要使用copy(DT)


来自?copy的文档:

  

data.table通过引用修改,并返回(不可见)   它可以用在复合语句中;例如,setkey(DT,a)[J("foo")]。   如果您需要副本,请先复制一份(使用DT2=copy(DT))。 copy()   在:=用于分配给a之前,有时也可能有用   列引用。请参阅?copy

另见这个问题: Understanding exactly when a data.table is a reference to vs a copy of another