2013-04-08 40 views
5

只是为了自己清理一些东西,我想更好地理解何时创建副本以及何时不在data.table中。由于这个问题指出Understanding exactly when a data.table is a reference to (vs a copy of) another data.table,如果简单地运行下列那么你最终修改原始:了解data.table的参考属性R

library(data.table) 

DT <- data.table(a=c(1,2), b=c(11,12)) 
print(DT) 
#  a b 
# [1,] 1 11 
# [2,] 2 12 

newDT <- DT  # reference, not copy 
newDT[1, a := 100] # modify new DT 

print(DT)   # DT is modified too. 
#  a b 
# [1,] 100 11 
# [2,] 2 12 

然而,如果做到这一点(例如),那么你最终修改的新版本:

DT = data.table(a=1:10) 
DT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

newDT = DT[a<11] 
newDT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

newDT[1:5,a:=0L] 

newDT 
    a 
1: 0 
2: 0 
3: 0 
4: 0 
5: 0 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

DT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

据我了解,之所以出现这种情况是因为当你执行i声明,data.table返回一个全新的表,而不是由旧data.table选择元素所占用的内存的引用。这是正确和真实的吗?

编辑:对不起,我的意思i没有j(高于此改变)

+0

即使'newDT < - DT [x <11]'也会创建一个副本。通过子集创建'newDT'后,'newDT [,b:= 5]'。使用'tracemem'和'.Internal(inspect(。))'是理解这一点的信息工具。 – Arun 2013-04-08 22:39:15

+0

@阿伦:对不起,我不确定我是否理解你的观点。你能解释一下你指的是什么吗?你的意思是说第一个例子和第二个例子会一样吗?在那种情况下是的 - 这是真的。我只是想要一个单独的例子来说清楚。 – Alex 2013-04-08 22:42:06

+0

当然,你能解释一下你指的是哪个'j'语句:'据我了解,这种情况发生的原因是因为当你执行一个j语句时,只是为了确定。我会用我之前谈论的内容写一个答案。 – Arun 2013-04-08 22:46:27

回答

7

当您在第二个例子中newDT,你正在评估i(不j)。 :=j参数内通过引用进行分配。在i语句中没有等价物,因为自引用通过分配列而不是行。

A data.table是一个列表。它的长度==列数,但在分配这样你就可以不用复制整个表(例如使用j:=

如果我们检查data.table,那么我们可以看到truelength添加更多的列(tl = 100) - 即列指针的时隙的numbe

.Internal(inspect(DT)) 
@1427d6c8 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=1, tl=100) 
    @b249a30 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,... 

的data.table每个元件内具有长度10,和tl=0。目前没有办法增加列的truelength,以允许通过引用附加额外的行。

?truelength

目前,它只是列指针列表载体,其是 超额分配(即truelength(DT)),而不是列向量 自己,将要在未来实现快速排插入()

当你评估idata.table不检查您是否仅返回在同一顺序的所有行作为原(再不敢在这种情况下,仅复制),它简单地返回副本。

+0

像往常一样优秀的答案!我会挽救尴尬并放弃我的回答:)。 – Arun 2013-04-08 22:59:56

+0

@mnel:我认为我对我的问题并不完全清楚,或者我不完全明白你的答案。我的意思是了解,当你评估'我',一个副本返回,而不是一个参考..是真的吗? – Alex 2013-04-08 23:17:34

+0

@Alex正确 - 我已经重写了我的最后陈述(二读时不是特别清楚) – mnel 2013-04-08 23:22:33