我有一个data.table myDT
,我正在制作"副本"这个表有三种不同的方式:
myDT <- data.table(colA = 1:3)
myDT[colA == 3]
copy1 <- copy(myDT)
copy2 <- myDT # yes I know that it's a reference, not real copy
copy3 <- myDT[,.(colA)] # I list all columns from the original table
然后我将这些副本与原始表格进行比较:
identical(myDT, copy1)
# TRUE
identical(myDT, copy2)
# TRUE
identical(myDT, copy3)
# FALSE
我试图找出myDT
和copy3
identical(names(myDT), names(copy3))
# TRUE
all.equal(myDT, copy3, check.attributes=FALSE)
# TRUE
all.equal(myDT, copy3, check.attributes=FALSE, trim.levels=FALSE, check.names=TRUE)
# TRUE
attr.all.equal(myDT, copy3, check.attributes=FALSE, trim.levels=FALSE, check.names=TRUE)
# NULL
all.equal(myDT, copy3)
# [1] "Attributes: < Length mismatch: comparison on first 1 components >"
attr.all.equal(myDT, copy3)
# [1] "Attributes: < Names: 1 string mismatch >"
# [2] "Attributes: < Length mismatch: comparison on first 3 components >"
# [3] "Attributes: < Component 3: Attributes: < Modes: list, NULL > >"
# [4] "Attributes: < Component 3: Attributes: < names for target but not for current > >"
# [5] "Attributes: < Component 3: Attributes: < current is not list-like > >"
# [6] "Attributes: < Component 3: Numeric: lengths (0, 3) differ >"
我最初的问题是如何理解最后的输出。最后我开始使用attributes()
函数:
attr0 <- attributes(myDT)
attr3 <- attributes(copy3)
str(attr0)
str(attr3)
它显示原始data.table
具有index
属性,在创建copy3
时未复制该属性。
答案 0 :(得分:4)
为了使这个问题更清晰一点(也许对未来的读者有用),这里真正发生的是你(可能不是)在显式调用{{1}时设置二级密钥 },OR,set2key
在进行一些普通操作(如过滤)时,似乎设置了辅助密钥。这是V 1.9.4中添加的(不是那样的)新功能
DT [column == value]和DT [%%in%values]现在已经过优化使用 密钥(DT)[1] ==&#34;列&#34;时的DT键,否则为辅助密钥(a.k.a. index)会自动添加,因此下一个DT [column == value]就是多了 快点。无需更改代码;现有代码应该自动进行 效益。可以使用set2key()和手动添加辅助键 使用key2()检查存在。这些优化和功能 名称/参数是实验性的,可以关闭 选项(datatable.auto.index = FALSE)。
让我们重现这个
data.table
因此,与您假设的不同,您实际上 创建了一个副本,因此辅助密钥并未随之传输。比较
myDT <- data.table(A = 1:3)
options(datatable.verbose = TRUE)
myDT[A == 3]
# Creating new index 'A' <~~~~ Here it is
# forder took 0 sec
# Coercing double column i.'V1' to integer to match type of x.'A'. Please avoid coercion for efficiency.
# Starting bmerge ...done in 0 secs
# A
# 1: 3
attr(myDT, "index") # or using `key2(myDT)`
# integer(0)
# attr(,"__A")
# integer(0)
进行进一步验证
copy1 <- myDT
attr(copy1, "index")
# integer(0)
# attr(,"__A")
# integer(0)
copy2 <- myDT[,.(A)]
# Detected that j uses these columns: A <~~~ This is where the copy occures
attr(copy2, "index")
# NULL
identical(myDT, copy1)
# [1] TRUE
identical(myDT, copy2)
# [1] FALSE
这里最有趣的结论是,tracemem(myDT)
# [1] "<00000000159CBBB0>"
tracemem(copy1)
# [1] "<00000000159CBBB0>"
tracemem(copy2)
# [1] "<000000001A5A46D8>"
创建副本,即使对象保持不变。