data.table 包能胜任各种数据操作,速度查快。其语法高度抽象、简洁、一致。

用i 选择行,用j 操作列,根据by 分组. 其中j表达式非常强大和灵活,可以选择,修改,汇总和计算新列。
引用语法“ := ”
data.table
设置键和引索,使得选择行、做数据连接更加方便快速(快170 倍)。
- 键:一级有序索引(在内存中做物理重排序)
-
索引:自动二级索引数学只保存为属性, ==, %in%()
image.png
特殊符号

管道操作
da[...][...][...]
批量读入
c("DT.csv", "DT.csv") %>%
lapply(fread) %>%
rbindlist() # 多个数据框/列表按行合并
vroom包提供了速度更快的文件读写函数:vroom, vroom_write()
非等连接(筛选范围值)
一般的连接是等值连接,即匹配列的值相等,才认为匹配成功。
很多时候需要非等连接,相当于是按条件连接,即匹配列的值不要求必须相等,只要满足一定条
件就认为是匹配成功,再将匹配成功的其他列连接进来。
滚动连接
滚动连接也是很有用的一种数据连接,往往涉及日期时间,特别是处理在时间上有先后关联的两
个事。
x[y, on = .(id = id, date = date), roll = TRUE] # 同roll = inf
根据id 等值匹配行,date 是滚动匹配,匹配与左表y 日期最接近的前一个日期,匹配成功的列
合并进来;roll = -inf 则匹配最接近的后一个日期
使用
首先创建用于连接的单独时间列
再设置key##这样就可以省略on语句

需要确定哪一个数据作为左表(连接起始)

可以做前 和后窗口连接, 并且可以做滚动窗口连接
数据重塑
宽变长
使用的语句:
每行只有一个观察值的情况:
data %>% melt(measure = , variable = " ", value = " " )## measure后面是整数向量指定要变形的列, variable增加新的列名字,value,值的去向设定,如果要忽略缺失值,设置: na.rm = T
tidyr::pivot_longer()也可以实现
每行只有多个个观察值的情况:
data %>% melt(measure = patterns(列明) , value = " ", na.rm=T )#
长变宽
只有1 个列名列和1 个值列的情形
data %>% dcast (year ~ Type, value = "Heads", fill = 0)##第一个参数是公式形式, ~左边是不变的列,右边是“变量名”来源,参数value指定“值”的来源
pivot_wider()
data %>% pivot_wider(names_from = Type, values_from_Heads, values_fill = 0)
有多个列名列和多个值列的情形

数据分割与合并
函数split(DT, by) 可将data.table 分割为list, 然后就可以接map_*() 函数逐分组迭代。
将rate列拆为两列,并且删除原列
data[, c("cases", "population") := tstrsplit(data$rate, split = "/")] [, rate := NULL]
合并列
data[, new := past0(century, year)] [, c("century", "year") := NULL]
数据操作
对行操作,使用data[i, j, by]中的i
选择行: dt[V4 %chin% c("A", "B")] ##比 %in%更快
unique()删除重复行
na.omit(data, cols = 1:4)## 删除1到4列,包含NA的行
行切片
data[sample(.N, 3)]## 随机抽取3行
data[sample(.N, .N* 0.5)] ## 随机抽取50% 的行
data[v4 %like% "^B"] ##V4列以B开头
data[v2 %between% c(3,6)] ###选择v2列中3到6的行,包含3与6
data[between (v2, 3, 5, incbounds = F)] ## 开区间
data [v2 %inrange% list (-1:1, 1:3)] ## v2列中多个区间值的选择
data[inrange(v2, -1:1. 1:3, incbounds = T)]## v2列中多个区间值的选择
排序order
data[order(v1)]
对行操作,使用data[i, j, by]中的j
根据引索
data[[3]]或者data[,3]
根据列名
data[, .(V3)]或者data[, .(v2, v3, v4)]
反引用列名
data.table 需要字符串函数、正则表达式构造出列名向量,再通过反引用选择相应的列。
首先确定需要选择的列名:


选取列:
data[, ..cols]
调整序列
cols = rev(names(DT)) ### 自己可以排序
setcolorder(DT, cols) ## 设定
修改列名
setnames(data, old, new)
修改因子水平
data[, setattr(sex, "levels", c("M", ""F))]
注意: data.table 是使用** := **直接对原数据框修改
修改或增加一列
data[, v1 := v1^2] ##只修改列
data[, v2 := v1^2 ## 增加v2列
data[, .(v2 = log(v1), v3 = v2 + 1) # 只保留新列,但是注意第二个v2使用的是原始v2
data[, c("v2","v3") := .(temp <- log(v1), v3 = temp +1)] ## 这里第二个v2使用的是新计算的列
同时增加多列
data[, ':=' (v6 = sqrt(v1),
v7 = "x")] ## v7列的值全为x
同时修改多列
需要借助lapply()和特殊符号:
.SD: 每个分组的数据子集, 除了by或者keyby的列
.SDcols: 与.SD 连用,用来选择包含在.SD 中的列,支持索引、列名、连选、反选、正则表达式、条件判断函数
应用函数到所有的列
data[, lapply(.SD, as.character)]
注意,上述同时修改多列的代码,都是只保留新列,若要保留所有列,需要准备新列名cols, 再在j 表达式中使用(cols) := ...
删除列
data [, c("v1", "v3") := NULL]
从新编码
data[v1 < 0, v1 := 0] ## 单个编码
data[, v1 := fifelse(v1 < 0, -v1, v1)]## 二分支
data[, v2 := fcase(v2 < 0, "low",
v2 < 4, "middle",
default = "high")]
前移/后移运算
shift(x, n= 1, fill = NA, type = "lag") ## 1, 2, 3 变为 NA, 1, 2
shift(x, n = 1, fill = NA, type = "lead") ## 1, 2, 3 变为 2, 3, NA
分组汇总
data.table 是根据by 或keyby分组,
区别是,keyby 会排序结果并创建键,使得更快地访问子集。
分组数据框,相当于整个数据框分成了m 个数据框,数据操作是分别在每个数据框上进行,若汇总则得到的是m 个结果。
简单的分组汇总
按性别分组计算
data[, .(n = .N,
math_avg = mean(math, na.rm = T),
math_med = median(math)),
by = sex]
对时间的处理IDataTime

对某些列做汇总
data[, lapply(.SD, mean), .SDcols = patterns("h"),
by = .(class, sex)]
对所有的列做汇总
data[, name := NULL][, lapply(.SD, mean, na.rm = T), by = .(class, sex)]
对满足条件的列做汇总
data[, lapply(.SD, mean, na.rm = T), by = class,
.SDcols = is.numeric]
分组计数
data[, Bin := cut(math, c(0, 60, 100))]
data[CJ(class = class, Bin = Bin, unique = TRUE),
on = c("class","Bin"), .N, by = .EACHI]
其中CJ() 相当于expand_grid(0, 生成所有两两组合
分组选择行
first(), last(), uniqueN(). 比如提取每组的first/nth 观测:

重点: 在使用中对于data[i, j, by], 同时对i 选择的行,根据by 分组,做j 操作
data.table 中习惯用lapply(), 换成map() 也是一样的,好处是支持函数的purrr-风格公式写法。
网友评论