【r<-包|数据操作】data.table包操作

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

语法格式:

DT[i, j, by]

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

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

install.packages("data.table")

导入包

library(data.table)

创建一个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"
img
##     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"))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容