前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「R」data.table 包功能特性学习

「R」data.table 包功能特性学习

作者头像
王诗翔呀
发布2020-07-03 16:22:07
1.9K0
发布2020-07-03 16:22:07
举报
文章被收录于专栏:优雅R优雅R

来自很久之前的官网文档。

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"))
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 优雅R 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建一个data.table
  • 使用索引i取子集
  • 对j列进行操作
  • 按组对列进行计算操作
  • 使用:=根据参考索引j添加和更新列
  • 索引和键
  • 高级data.table操作
  • .SD 与 .SDcols
  • set家族
    • set()
      • setnames()
        • setnames()
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档