data.table包提供了一个加强版的data.frame。它运行效率极高,而且能够处理适合内存的大数据集。它通过[ ]实现了一种自然的数据操作语法。

语法格式:

DT[i, j, by]

释义为对data.table对象DT,使用i选择行,然后按照by计算j

如果你还没有安装该包,运行:

install.packages("data.table")

导入包

library(data.table)
## Warning: 程辑包'data.table'是用R版本3.5.1 来建造的

创建一个data.table

set.seed(45L)
DT <- data.table(V1 = c(1L, 2L),
                 V2 = LETTERS[1:3],
                 V3 = round(rnorm(4), 4),
                 V4 = 1:12)

使用索引i取子集

# 选择第3到5行
DT[3:5, ]
##    V1 V2     V3 V4
## 1:  1  C -0.380  3
## 2:  2  A -0.746  4
## 3:  1  B  0.341  5
# 选择第3到5行
DT[3:5]
##    V1 V2     V3 V4
## 1:  1  C -0.380  3
## 2:  2  A -0.746  4
## 3:  1  B  0.341  5
# 选择第二列V2有值为A的列
DT[V2=="A"]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  2  A -0.746  4
## 3:  1  A -0.380  7
## 4:  2  A -0.703 10
# 选择第二列有A或C的列
DT[V2 %in% c("A", "C")]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  1  C -0.380  3
## 3:  2  A -0.746  4
## 4:  2  C -0.703  6
## 5:  1  A -0.380  7
## 6:  1  C  0.341  9
## 7:  2  A -0.703 10
## 8:  2  C -0.746 12

对j列进行操作

# 返回第二列为一个向量
DT[, V2]
##  [1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C"
# 返回第二列与第三列为一个data.table
DT[, .(V2, V3)]
##     V2     V3
##  1:  A  0.341
##  2:  B -0.703
##  3:  C -0.380
##  4:  A -0.746
##  5:  B  0.341
##  6:  C -0.703
##  7:  A -0.380
##  8:  B -0.746
##  9:  C  0.341
## 10:  A -0.703
## 11:  B -0.380
## 12:  C -0.746
# 返回V1列所有元素和为一个向量
DT[, sum(V1)]
## [1] 18
# 返回V1列的和,V3列的标准差为一个data.table
DT[, .(sum(V1), sd(V3))]
##    V1    V2
## 1: 18 0.455
# 跟上面一样,但生成新的列名
DT[, .(Aggregate=sum(V1), Sd.V3=sd(V3))]
##    Aggregate Sd.V3
## 1:        18 0.455
# 选择V2列和计算V3列的标准差
DT[, .(V1, Sd.V3=sd(V3))]
##     V1 Sd.V3
##  1:  1 0.455
##  2:  2 0.455
##  3:  1 0.455
##  4:  2 0.455
##  5:  1 0.455
##  6:  2 0.455
##  7:  1 0.455
##  8:  2 0.455
##  9:  1 0.455
## 10:  2 0.455
## 11:  1 0.455
## 12:  2 0.455
# 对V2列打印,对V3列绘图
DT[, .(print(V2), plot(V3), NULL)]
##  [1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C"

##     V1
##  1:  A
##  2:  B
##  3:  C
##  4:  A
##  5:  B
##  6:  C
##  7:  A
##  8:  B
##  9:  C
## 10:  A
## 11:  B
## 12:  C

按组对列进行计算操作

# 对V1的每一组计算V4的和
DT[, .(V4.sum=sum(V4)), by=V1]
##    V1 V4.sum
## 1:  1     36
## 2:  2     42
# 对V1和V2的每组计算V4的和
DT[, .(V4.sum=sum(V4)), by=.(V1,V2)]
##    V1 V2 V4.sum
## 1:  1  A      8
## 2:  2  B     10
## 3:  1  C     12
## 4:  2  A     14
## 5:  1  B     16
## 6:  2  C     18
# 对sign(V1-1)的每组计算V4的和
DT[, .(V4.sum=sum(V4)), by=sign(V1-1)]
##    sign V4.sum
## 1:    0     36
## 2:    1     42
# 跟上面一样,但给分组变量取一个新的名字
DT[, .(V4.sum=sum(V4)), by=.(V1.01=sign(V1-1))]
##    V1.01 V4.sum
## 1:     0     36
## 2:     1     42
# 先取前5行,然后对V1的每组求V4的和
DT[1:5, .(V4.sum=sum(V4)), by=V1]
##    V1 V4.sum
## 1:  1      9
## 2:  2      6
# 对V1的每组计算行数
DT[, .N, by=V1]
##    V1 N
## 1:  1 6
## 2:  2 6

使用:=根据参考索引j添加和更新列

# 根据计算结果更新V1列
DT[, V1:=round(exp(V1), 2)]
DT
##       V1 V2     V3 V4
##  1: 2.72  A  0.341  1
##  2: 7.39  B -0.703  2
##  3: 2.72  C -0.380  3
##  4: 7.39  A -0.746  4
##  5: 2.72  B  0.341  5
##  6: 7.39  C -0.703  6
##  7: 2.72  A -0.380  7
##  8: 7.39  B -0.746  8
##  9: 2.72  C  0.341  9
## 10: 7.39  A -0.703 10
## 11: 2.72  B -0.380 11
## 12: 7.39  C -0.746 12

# 更新两列,使用[]可以将结果输出到屏幕
DT[, c("V1", "V2"):=list(round(exp(V1), 2),
                         LETTERS[4:6])]
DT[, ':='(V1=round(exp(V1),2),
          V2=LETTERS[4:6])][]
##          V1 V2     V3 V4
##  1: 3913724  D  0.341  1
##  2:     Inf  E -0.703  2
##  3: 3913724  F -0.380  3
##  4:     Inf  D -0.746  4
##  5: 3913724  E  0.341  5
##  6:     Inf  F -0.703  6
##  7: 3913724  D -0.380  7
##  8:     Inf  E -0.746  8
##  9: 3913724  F  0.341  9
## 10:     Inf  D -0.703 10
## 11: 3913724  E -0.380 11
## 12:     Inf  F -0.746 12
# 移除V1列
DT[, V1:=NULL]
# 移除V1列和V2列
DT[, c("V1", "V2"):=NULL]

# 删除有列名Cols.chosen的列
Clos.chosen = c("A", "B")
DT[, Clos.chosen:=NULL][]
##         V3 V4
##  1:  0.341  1
##  2: -0.703  2
##  3: -0.380  3
##  4: -0.746  4
##  5:  0.341  5
##  6: -0.703  6
##  7: -0.380  7
##  8: -0.746  8
##  9:  0.341  9
## 10: -0.703 10
## 11: -0.380 11
## 12: -0.746 12

# 删除列名指定在Cols.chosen中的列
DT[, (Clos.chosen):=NULL][]
##         V3 V4
##  1:  0.341  1
##  2: -0.703  2
##  3: -0.380  3
##  4: -0.746  4
##  5:  0.341  5
##  6: -0.703  6
##  7: -0.380  7
##  8: -0.746  8
##  9:  0.341  9
## 10: -0.703 10
## 11: -0.380 11
## 12: -0.746 12

索引和键

# 对V2列设定一个键,输出返回不可视
# 返回满足键列(V2)值为A的所有行
setkey(DT, V2)
DT["A"]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  2  A -0.746  4
## 3:  1  A -0.380  7
## 4:  2  A -0.703 10
# V2列为A或C的所有行
DT[c("A", "C")]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  2  A -0.746  4
## 3:  1  A -0.380  7
## 4:  2  A -0.703 10
## 5:  1  C -0.380  3
## 6:  2  C -0.703  6
## 7:  1  C  0.341  9
## 8:  2  C -0.746 12
# V2列为A的第一个匹配行
DT["A", mult="first"]
##    V1 V2    V3 V4
## 1:  1  A 0.341  1
# 最后一个匹配行
DT["A", mult="last"]
##    V1 V2     V3 V4
## 1:  2  A -0.703 10

# 返回所有V2列有A或D值的行
DT[c("A", "D")]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  2  A -0.746  4
## 3:  1  A -0.380  7
## 4:  2  A -0.703 10
## 5: NA  D     NA NA
# 注意与上面的不同
DT[c("A", "D"), nomatch=0]
##    V1 V2     V3 V4
## 1:  1  A  0.341  1
## 2:  2  A -0.746  4
## 3:  1  A -0.380  7
## 4:  2  A -0.703 10
# 返回键列V2有A或C值行V4列的和
DT[c("A", "C"), sum(V4)]
## [1] 52
# 对A,C分别求和
DT[c("A", "C"), sum(V4), by=.EACHI]
##    V2 V1
## 1:  A 22
## 2:  C 30
# 设定键,先按V1排序然后按V2排序
setkey(DT, V1, V2)
# 返回V1满足2,V2满足C的行
DT[, .(2, "C")]
##    V1 V2
## 1:  2  C
# 返回V1满足2,V2满足A,C的行
DT[, .(2, c("A", "C"))]
##    V1 V2
## 1:  2  A
## 2:  2  C

高级data.table操作

# 返回倒数第二行
DT[.N-1]
##    V1 V2    V3 V4
## 1:  1  B -0.38 11
# 返回行数
DT[, .N]
## [1] 12
# 返回V2,V3为一个data.table
DT[, .(V2, V3)]
##     V2     V3
##  1:  A  0.341
##  2:  B -0.703
##  3:  C -0.380
##  4:  A -0.746
##  5:  B  0.341
##  6:  C -0.703
##  7:  A -0.380
##  8:  B -0.746
##  9:  C  0.341
## 10:  A -0.703
## 11:  B -0.380
## 12:  C -0.746
# 同上, list等价于.
DT[, list(V2, V3)]
##     V2     V3
##  1:  A  0.341
##  2:  B -0.703
##  3:  C -0.380
##  4:  A -0.746
##  5:  B  0.341
##  6:  C -0.703
##  7:  A -0.380
##  8:  B -0.746
##  9:  C  0.341
## 10:  A -0.703
## 11:  B -0.380
## 12:  C -0.746
# 按V1,V2分组,返回V3的均值
DT[, mean(V3), by=.(V1,V2)]
##    V1 V2      V1
## 1:  1  A -0.0194
## 2:  2  B -0.7247
## 3:  1  C -0.0194
## 4:  2  A -0.7247
## 5:  1  B -0.0194
## 6:  2  C -0.7247

.SD 与 .SDcols

# 看.SD包含什么
DT[, print(.SD), by=V2]
##    V1     V3 V4
## 1:  1  0.341  1
## 2:  2 -0.746  4
## 3:  1 -0.380  7
## 4:  2 -0.703 10
##    V1     V3 V4
## 1:  2 -0.703  2
## 2:  1  0.341  5
## 3:  2 -0.746  8
## 4:  1 -0.380 11
##    V1     V3 V4
## 1:  1 -0.380  3
## 2:  2 -0.703  6
## 3:  1  0.341  9
## 4:  2 -0.746 12
## Empty data.table (0 rows) of 1 col: V2
# 选择第一行与最后一行
DT[, .SD[c(1, .N)], by=V2]
##    V2 V1     V3 V4
## 1:  A  1  0.341  1
## 2:  A  2 -0.703 10
## 3:  B  2 -0.703  2
## 4:  B  1 -0.380 11
## 5:  C  1 -0.380  3
## 6:  C  2 -0.746 12
# 按V2计算.SD中所有列的和
DT[, lapply(.SD, sum), by=V2]
##    V2 V1    V3 V4
## 1:  A  6 -1.49 22
## 2:  B  6 -1.49 26
## 3:  C  6 -1.49 30
# 按V2计算.SD中V3,V4列的和
DT[, lapply(.SD, sum), by=V2, .SDcols=c("V3", "V4")]
##    V2    V3 V4
## 1:  A -1.49 22
## 2:  B -1.49 26
## 3:  C -1.49 30

# 按V1分组求V4列的和
DT2 <- DT[, .(V4.sum=sum(V4)), by=V1]
# 选择和>40的行
DT2[V4.sum>40]
##    V1 V4.sum
## 1:  2     42
# 按V1分组,V1排序计算V4和
DT[, .(V4.sum=sum(V4)), by=V1][order(-V1)]
##    V1 V4.sum
## 1:  2     42
## 2:  1     36

set家族

set()

语法:

for (i in from:to) set(DT, row, column, new_value)
rows <- list(3:4, 5:6)
cols <- 1:2
for (i in seq_along(rows)) {
    set(DT,
        i=rows[[i]],
        j=cols[[i]],
        value=NA)
}

setnames()

语法:

setnames(DT, "old", "new")
setnames(DT, "V2", "Rating")
setnames(DT, c("V2","V3"),
         c("V2.rating", "V3.DC"))

setnames()

列排序

语法:

setcolorder(DT, "neworder")
setcolorder(DT, c("V2", "V1", "V4", "V3"))