赞
踩
data.table 包是 data.frame 的高性能版本,不依赖其它包就能胜任各种数据操作,速度超快,让个人电脑都能轻松处理几 G 甚至几十 G 的数据。data.table 的高性能来源于内存管理(引用语法)、并行化和大量精细优化。
但是,与 tidyverse 一次用一个函数做一件事,通过管道依次连接整洁地完成复杂事情 的理念截然不同,data.table 语法高度抽象、简洁、一致:
一句话概括:用 i 选择行,用 j 操作列,根据 by 分组。
其中,j 表达式非常强大和灵活,可以选择、修改、汇总、计算新列,甚至可以接受任意表达式。需要记住的最关键一点是:只要返回等长元素或长度为 1 元素的 list,每个 list 元素将转化为结果 data.table 的一列。
data.table 高度抽象的语法无疑增加了学习成本,但它的高效性能和处理大数据能力,使得非常有必要学习它。当然,读者如果既想要 data.table 的高性能,又想要 tidyverse 的整洁语法,也可以借助一些衔接二者的中间包,如 dtplyr, tidyfst 等。
为了节省篇幅,本节将只展示代码演示 data.table 语法,尽量忽略输出结果;有些复杂操作采用同前文一样的数据,得到同样的结果(故略过)。
创建 data.table
- library(data.table)
- dt = data.table(
- x = 1:2,
- y = c("A", "B")
- )
- dt
用 as.data.table()
可将数据框、列表、矩阵等转化为 data.table;若只想按引用转化,用 setDT()
.
引用语法
高效计算的编程都支持引用语法,也叫浅拷贝。
浅拷贝【脚注1】,只是拷贝列指针向量(对应数据框的列),而实际数据在内存中不做物理拷贝;而相对的概念:深拷贝,则拷贝整个数据到内存中的另一位置,深拷贝这种冗余的拷贝极大地影响性能,特别是大数据的情形。
脚注1:引用语法,相当于是对象只有一个在内存放着,不做多余复制,用两个指针都指向该同一对象,操作哪个指针,都是在修改该同一对象.
data.table 使用 :=
算符,做整列或部分列替换时都不做任何拷贝,因为 :=
算符是通过引用就地(in-place)更新 data.table 的列。
若想要复制不想按引用(修改数据本身),使用 DT2 = copy(DT1)
.
键与索引
data.table 支持设置键和索引,使得选择行、做数据连接更加方便快速(快170 倍)。
- setkey(dt, v1, v3) # 设置键
- setindex(dt, v1, v3) # 设置索引
二者的主要不同:
==
或 %in%
时);
on
连用;键的使用是可选的,但为了可读性建议使用键。特殊符号
data.table 提供了一些辅助操作的特殊符号:
.()
: 代替 list()
:=
: 按引用方式增加、修改列.N
: 行数.SD
: 每个分组的数据子集,除了 by
或 keyby
的列.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 也有自己专用的管道操作,称为链式操作:
- DT[⋯][⋯][⋯] # 或者写开为
- DT[
- ⋯
- ][
- ⋯
- ][
- ⋯
- ]
函数 fread()
和 fwrite()
是data.table 最强大的函数之二。它们最大的优势,仍是读取大数据时速度超快(100 倍),且非常稳健,分隔符、列类型、行数都是自动检测;它们非常通用,可以处理不同的文件格式(但不能直接读取 Excel 文件),还可以接受 URLs 甚至是操作系统指令。
读入数据
- fread("DT.csv")
- fread("DT.txt", sep = "t")
- # 选择部分行列读取
- fread("DT.csv", select = c("V1", "V4"))
- fread("DT.csv", drop = "V4", nrows = 100)
- # 读取压缩文件
- fread(cmd = "unzip -cq myfile.zip")
- fread("myfile.gz")
- # 批量读取
- c("DT.csv", "DT.csv") %>%
- lapply(fread) %>%
- rbindlist() # 多个数据框/列表按行合并
写出数据
- fwrite(DT, "DT.csv")
- fwrite(DT, "DT.csv", append = TRUE) # 追加内容
- fwrite(DT, "DT.txt", sep = "t")
- fwrite(setDT(list(0, list(1:5))), "DT2.csv") # 支持写出列表列
- fwrite(DT, "myfile.csv.gz", compress
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。