当我通过引用分配所有列时,为什么data.table会自动转换

时间:2013-09-03 13:48:53

标签: r data.table

data.table以下是我无法理解的内容 如果我选择一行,并尝试将此行的所有值设置为NA,则新的l​​ine-data.table将转换为逻辑

#Here is a sample table
DT <- data.table(a=rep(1L,3),b=rep(1.1,3),d=rep('aa',3))
DT
   a   b  d
1: 1 1.1 aa
2: 1 1.1 aa
3: 1 1.1 aa

#Here I extract a line, all the column types are kept... good
str(DT[1])
Classes ‘data.table’ and 'data.frame':  1 obs. of  3 variables:
 $ a: int 1
 $ b: num 1.1
 $ d: chr "aa"
 - attr(*, ".internal.selfref")=<externalptr> 

#Now here I want to set them all to NA...they all become logicals => WHY IS THAT ?
str(DT[1][,colnames(DT):=NA])
Classes ‘data.table’ and 'data.frame':  1 obs. of  3 variables:
 $ a: logi NA
 $ b: logi NA
 $ d: logi NA
 - attr(*, ".internal.selfref")=<externalptr> 

编辑:我认为这是一个错误

R) str(DT[1][,a:=NA])
Classes ‘data.table’ and 'data.frame':  1 obs. of  3 variables:
 $ a: logi NA
 $ b: num 1.1
 $ d: chr "aa"
 - attr(*, ".internal.selfref")=<externalptr> 
R) str(DT[1:2][,a:=NA])
Classes ‘data.table’ and 'data.frame':  2 obs. of  3 variables:
 $ a: int  NA NA
 $ b: num  1.1 1.1
 $ d: chr  "aa" "aa"
 - attr(*, ".internal.selfref")=<externalptr> 

1 个答案:

答案 0 :(得分:8)

?":="

提供答案
  

与&lt; - 对于data.frame不同,(可能很大的)LHS不会被强制匹配(通常很小的)RHS的类型。相反,如有必要,RHS会被强制匹配LHS的类型。如果这涉及将双精度值强制转换为整数列,则会给出警告(是否截断了小数数据)。这样做的动机是效率。最好让前面的列类型正确并坚持下去。 更改列类型是可能的,但故意更难:提供整列作为RHS。然后将此RHS插入到该列插槽中,我们调用此plonk语法,或者如果您愿意,请替换列语法。 通过构建新类型的全长向量,您可以更好地了解正在发生的事情,并且您的代码读者更清楚您确实打算更改列类型

当然,所有这一切的动机都是大表(比如RAM中的10GB)。不是1或2行表。

更简单地说:如果长度(RHS)== nrow(DT),则RHS(及其类型) plonked 进入该列槽。即使这些长度是1.如果长度(RHS)<1。 nrow(DT),列的内存(及其类型)保持不变,但RHS被强制并循环使用替换该列中的(子集)项目。

如果我需要在大表中更改列的类型,我写道:

DT[, col := as.numeric(col)]

这里as.numeric分配一个新的向量,将col强制转换为新的内存,然后将其插入到列槽中。它尽可能高效。原因是长度(RHS)= = nrow(DT)。

如果要覆盖包含某个默认值的其他类型的列:

DT[, col := rep(21.5,nrow(DT))]    # i.e., deliberately harder

如果col之前是整数类型,那么它将改为键入包含每行21.5的数字。否则只有DT[, col := 21.5]会导致21.5被强制为21的警告(除非DT只有1行!)