来自很久之前的官网文档。
data.table
包提供了一个加强版的data.frame
。它运行效率极高,而且能够处理适合内存的大数据集。它通过[ ]
实现了一种自然的数据操作语法。
语法格式:
代码语言:javascript复制DT[i, j, by]
释义为对data.table对象DT,使用i选择行,然后按照by计算j。
如果你还没有安装该包,运行:
代码语言:javascript复制install.packages("data.table")
导入包
代码语言:javascript复制library(data.table)
创建一个data.table
代码语言:javascript复制set.seed(45L)
DT <- data.table(V1 = c(1L, 2L),
V2 = LETTERS[1:3],
V3 = round(rnorm(4), 4),
V4 = 1:12)
使用索引i取子集
代码语言:javascript复制# 选择第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列进行操作
代码语言:javascript复制# 返回第二列为一个向量
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"
img
代码语言:javascript复制## 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
按组对列进行计算操作
代码语言:javascript复制# 对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添加和更新列
代码语言:javascript复制# 根据计算结果更新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
索引和键
代码语言:javascript复制# 对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操作
代码语言:javascript复制# 返回倒数第二行
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
代码语言:javascript复制# 看.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
链
代码语言:javascript复制# 按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()
语法:
代码语言:javascript复制for (i in from:to) set(DT, row, column, new_value)
代码语言:javascript复制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()
语法:
代码语言:javascript复制setnames(DT, "old", "new")
代码语言:javascript复制setnames(DT, "V2", "Rating")
setnames(DT, c("V2","V3"),
c("V2.rating", "V3.DC"))
setnames()
列排序
语法:
代码语言:javascript复制setcolorder(DT, "neworder")
setcolorder(DT, c("V2", "V1", "V4", "V3"))