当前位置:   article > 正文

大量数据table_【R语言新书】2.7 数据处理神器:data.table包

tidyverse data.table

32580eda7d26fa43b0ce74c1e0d0093c.png
张敬信:《R语言编程—基于tidyverse》新书信息汇总​zhuanlan.zhihu.com
bbd1d15c8fe99a17cdb4723894b2c424.png

2.7 数据处理神器:data.table 包

data.table 包是 data.frame 的高性能版本,不依赖其它包就能胜任各种数据操作,速度超快,让个人电脑都能轻松处理几 G 甚至几十 G 的数据。data.table 的高性能来源于内存管理(引用语法)、并行化和大量精细优化。

但是,与 tidyverse 一次用一个函数做一件事,通过管道依次连接整洁地完成复杂事情 的理念截然不同,data.table 语法高度抽象、简洁、一致:

b20f23ca1fcf6afcf5e5dc62cb26ad15.png

一句话概括:用 i 选择行,用 j 操作列,根据 by 分组

其中,j 表达式非常强大和灵活,可以选择、修改、汇总、计算新列,甚至可以接受任意表达式。需要记住的最关键一点是:只要返回等长元素或长度为 1 元素的 list,每个 list 元素将转化为结果 data.table 的一列。

data.table 高度抽象的语法无疑增加了学习成本,但它的高效性能和处理大数据能力,使得非常有必要学习它。当然,读者如果既想要 data.table 的高性能,又想要 tidyverse 的整洁语法,也可以借助一些衔接二者的中间包,如 dtplyr, tidyfst 等。

为了节省篇幅,本节将只展示代码演示 data.table 语法,尽量忽略输出结果;有些复杂操作采用同前文一样的数据,得到同样的结果(故略过)。

2.7.1 通用语法

创建 data.table

  1. library(data.table)
  2. dt = data.table(
  3. x = 1:2,
  4. y = c("A", "B")
  5. )
  6. dt

d9047023fc0e025dee9c4d4ce10abd51.png

as.data.table() 可将数据框、列表、矩阵等转化为 data.table;若只想按引用转化,用 setDT().

引用语法

高效计算的编程都支持引用语法,也叫浅拷贝。

浅拷贝【脚注1】,只是拷贝列指针向量(对应数据框的列),而实际数据在内存中不做物理拷贝;而相对的概念:深拷贝,则拷贝整个数据到内存中的另一位置,深拷贝这种冗余的拷贝极大地影响性能,特别是大数据的情形。

脚注1:引用语法,相当于是对象只有一个在内存放着,不做多余复制,用两个指针都指向该同一对象,操作哪个指针,都是在修改该同一对象.

data.table 使用 := 算符,做整列或部分列替换时都不做任何拷贝,因为 := 算符是通过引用就地(in-place)更新 data.table 的列。

若想要复制不想按引用(修改数据本身),使用 DT2 = copy(DT1).

键与索引

data.table 支持设置键和索引,使得选择行、做数据连接更加方便快速(快170 倍)。

  • :一级有序索引
  • 索引:自动二级索引
  1. setkey(dt, v1, v3) # 设置键
  2. setindex(dt, v1, v3) # 设置索引

二者的主要不同:

  • 使用键时,数据在内存中做物理重排序;而使用索引时,顺序只是保存为属性;
  • 键是显式定义的;索引可以手动创建,也可以运行时创建(比如用 ==%in%

时);

  • 索引与参数 on 连用;键的使用是可选的,但为了可读性建议使用键。

特殊符号

data.table 提供了一些辅助操作的特殊符号:

  • .(): 代替 list()
  • :=: 按引用方式增加、修改列
  • .N: 行数
  • .SD: 每个分组的数据子集,除了 bykeyby 的列
  • .SDcols: 与 .SD 连用,用来选择包含在 .SD 中的列
  • .BY: 包含所有 by 分组变量的 list
  • .I: 整数向量 seq_len(nrow(x)),例如 DT[, .I[which.max(somecol)], by=grp]
  • .GRP: 分组索引,1 代表第 1 分组,2 代表第 2 分组,. . .
  • .NGRP: 分组数
  • .EACHI: 用于 by/keyby = .EACHI 表示根据 i 表达式的每一行分组

链式操作

data.table 也有自己专用的管道操作,称为链式操作:

  1. DT[⋯][⋯][⋯] # 或者写开为
  2. DT[
  3. ][
  4. ][
  5. ]

2.7.2 数据读写

函数 fread()fwrite() 是data.table 最强大的函数之二。它们最大的优势,仍是读取大数据时速度超快(100 倍),且非常稳健,分隔符、列类型、行数都是自动检测;它们非常通用,可以处理不同的文件格式(但不能直接读取 Excel 文件),还可以接受 URLs 甚至是操作系统指令。

读入数据

  1. fread("DT.csv")
  2. fread("DT.txt", sep = "t")
  3. # 选择部分行列读取
  4. fread("DT.csv", select = c("V1", "V4"))
  5. fread("DT.csv", drop = "V4", nrows = 100)
  6. # 读取压缩文件
  7. fread(cmd = "unzip -cq myfile.zip")
  8. fread("myfile.gz")
  9. # 批量读取
  10. c("DT.csv", "DT.csv") %>%
  11. lapply(fread) %>%
  12. rbindlist() # 多个数据框/列表按行合并

写出数据

  1. fwrite(DT, "DT.csv")
  2. fwrite(DT, "DT.csv", append = TRUE) # 追加内容
  3. fwrite(DT, "DT.txt", sep = "t")
  4. fwrite(setDT(list(0, list(1:5))), "DT2.csv") # 支持写出列表列
  5. fwrite(DT, "myfile.csv.gz", compress
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/579644
推荐阅读
相关标签
  

闽ICP备14008679号