在使用不同的赋值运算符时,我注意到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
预计会出现这种情况吗?
答案 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