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

作者: 王诗翔 | 来源:发表于2018-05-07 01:01 被阅读59次

    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"))
    

    相关文章

      网友评论

        本文标题:【r<-包|数据操作】data.table包操作

        本文链接:https://www.haomeiwen.com/subject/ojgprftx.html