使用 data.frame 时,改变列名或者排序,都会导致数据结构的复制。在最新版本的 R
中,对列重命名已经很少复制了,但要实现完全不进行任何复制就能将某列重新排序,仍
然很困难。当数据量较小的时候,还不是问题,如果数据非常大的话,这种操作对性能和
内存造成的压力可能就比较麻烦了。
作为 data.frame 的加强版,data.table 提供了一系列支持引用语义的 set 函数,也
就是说,它们可以原地修改data.table ,从而避免了不必要的复制,展现出来惊人的性能。
仍以 product_stats 为例。我们可以调用函数 setDF( ) ,不需要任何复制,便可
以将 data.table 转换为 data.frame:
product_stats
## id material size weight density
## 1: M01 Plastics 50 NA NA
## 2: M02 Plastics 85 3.0 28.333333
## 3: M03 Wood 15 NA NA
## 4: M04 Wood 16 0.6 26.666667
## 5: T01 Metal 120 10.0 12.000000
## 6: T02 Metal 350 45.0 7.777778
setDF(product_stats)
class(product_stats)
## [1] "data.frame"
其实,setDT( )可以将任意的 data.frame 转换为 data.table,并设置键(如果
指定了的话):
setDT(product_stats, key = "id")
class(product_stats)
## [1] "data.table" "data.frame"
调用 setnames( ) 对列重命名:
setnames(product_stats, "size", "volume")
product_stats
## id material volume weight density
## 1: M01 Plastics 50 NA NA
## 2: M02 Plastics 85 3.0 28.333333
## 3: M03 Wood 15 NA NA
## 4: M04 Wood 16 0.6 26.666667
## 5: T01 Metal 120 10.0 12.000000
## 6: T02 Metal 350 45.0 7.777778
如果我们添加了一个新列,这一列应该作为最后一列。例如,给所有行添加一个索引,
即新加一列索引值,用 . I 表示 1:.N:
product_stats[, i := .I]
product_stats
## id material volume weight density i
## 1: M01 Plastics 50 NA NA 1
## 2: M02 Plastics 85 3.0 28.333333 2
## 3: M03 Wood 15 NA NA 3
## 4: M04 Wood 16 0.6 26.666667 4
## 5: T01 Metal 120 10.0 12.000000 5
## 6: T02 Metal 350 45.0 7.777778 6
方便起见,大多数情况下,索引出现在第 1 列。为了实现这一目的,我们可以调用
setcolorder( ) 函数,提供一个合意的列名顺序,这样不用复制,便可以直接调换列的顺序:
setcolorder(product_stats,
c("i", "id", "material", "weight", "volume", "density"))
product_stats
## i id material weight volume density
## 1: 1 M01 Plastics NA 50 NA
## 2: 2 M02 Plastics 3.0 85 28.333333
## 3: 3 M03 Wood NA 15 NA
## 4: 4 M04 Wood 0.6 16 26.666667
## 5: 5 T01 Metal 10.0 120 12.000000
## 6: 6 T02 Metal 45.0 350 7.777778