R 为什么data.table通过引用更新名称(DT),即使我分配给另一个变量?

R 为什么data.table通过引用更新名称(DT),即使我分配给另一个变量?,r,data.table,R,Data.table,我已将数据表的名称存储为向量: library(data.table) set.seed(42) DT <- data.table(x = runif(100), y = runif(100)) names1 <- names(DT) 然而,这不是普通的字符向量。这是一个神奇的角色向量!当我向我的data.table中添加一个新列时,这个向量会被更新 DT[ , z := runif(100)] names1 # [1] "x" "y" "z" 我知道这与:=如何通过分配进行更新

我已将
数据表的名称存储为
向量

library(data.table)
set.seed(42)
DT <- data.table(x = runif(100), y = runif(100))
names1 <- names(DT)
然而,这不是普通的字符向量。这是一个神奇的角色向量!当我向我的
data.table
中添加一个新列时,这个向量会被更新

DT[ , z := runif(100)]
names1
# [1] "x" "y" "z"
我知道这与
:=
如何通过分配进行更新有关,但这对我来说仍然很神奇,因为我希望
更新:这现在添加到1.9.3版的
?复制
文档中。发件人:
  • 移动
    ?将
    复制到它自己的帮助页面,并记录
    dtu名称感谢您提供的信息。我刚发现
    .Internal(inspect())
    ,我自己也开始到达那里。我想我没有意识到基本向量实际上在内部可以是对
    数据表的引用。我一直认为只有
    数据。表
    可以在内部是对
    数据表的引用。这很有趣。我想知道到底是怎么回事,迫使
    名称
    在赋值时不复制向量?而且,我想这种混乱是因为这对我来说也是新闻,是个大问题。名称向量和列指针向量被过度分配。当
    :=
    指定一个新列时,它也会通过引用更新名称向量。这可以通过不过度分配名称向量来改变/修复。但是如果在循环中添加列,速度会稍微慢一些。所以最好记录下
    nmahhh,Arun,这就是你提到的评论!(感谢@statquant的链接)。Matthew,我同意文档应该强调在任何时候都使用
    copy
    ,只要副本是副本。至于问题的根源,我很确定这是由于对
    伟大问题的懒惰评估!根据阿伦的回答,我已经提交了文件,记录了
    nm
    
    DT[ , z := runif(100)]
    names1
    # [1] "x" "y" "z"
    
    library(data.table)
    set.seed(42)
    DT <- data.table(x = runif(100), y = runif(100))
    
    names1 <- names(DT)
    names2 <- c(names(DT))
    all.equal(names1, names2)
    # [1] TRUE
    
    DT[ , z := runif(100)]
    names1
    # [1] "x" "y" "z"
    
    names2
    # [1] "x" "y"
    
    DT <- data.table(x = 1:5, y= 6:10)
    # assign DT2 to DT
    DT2 <- DT # assign by reference, no copy taken.
    DT2[, z := 11:15]
    # DT will also have the z column
    
    DT2 <- copy(DT) # copied content to DT2
    DT2[, z := 11:15] # only DT2 is affected
    
    .Internal(inspect(names1))
    # @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100)
    #   @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x"
    #   @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y"
    
    .Internal(inspect(names(DT)))
    # @7fc86a851480 16 STRSXP g0c7 [MARK,NAM(2)] (len=2, tl=100)
    #   @7fc86a069f68 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "x"
    #   @7fc86a0f96d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "y"
    
    truelength(names1)
    # [1] 100