7.2 常规操作
7.2.1 行筛选
上文已经大致讲过行筛选,但是行筛选使用有一定的技巧,涉及到运算的快慢。主要是逻辑条件的设置,交集并集之间的差异。除了上文中的关系运算筛选,逻辑运算筛选除外,data.table中还有几个常用的筛选函数。
- 数字向量筛选
%in%用法与 sql 中 in 用法类似。
# 筛选 %in%
%in% seq(1,24,2) ] flights[ hour
- 字符向量筛选
%chin%用法与 %in% 类似,但仅仅针对字符。
# 字符筛选
%chin% c('JFK','LGA')]
flights[ origin # not run 同上 %chin% 对字符速度筛选速度更快
#flights[ origin %in% c('JFK','LGA')]
- between 筛选
该函数的新特性矢量化挺实用。
#between 函数参数
#between(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
<- data.table(a=1:5, b=6:10, c=c(5:1))
X %between% c(7,9)]
X[b #> a b c
#> 1: 2 7 4
#> 2: 3 8 3
#> 3: 4 9 2
between(b, 7, 9)] #效果同上
X[#> a b c
#> 1: 2 7 4
#> 2: 3 8 3
#> 3: 4 9 2
%between% list(a,b)] # 矢量化
X[c #> a b c
#> 1: 1 6 5
#> 2: 2 7 4
#> 3: 3 8 3
- like 筛选
%like% 用法与SQL中 like 类似。
# %like% 用法与SQL中 like 类似
= data.table(Name=c("Mary","George","Martha"), Salary=c(2,3,4))
DT %like% "^Mar"]
DT[Name #> Name Salary
#> 1: Mary 2
#> 2: Martha 4
7.2.2 新增更新列
新增或删除或更新列是我们数据清洗过程中的常规操作,data.table中
实现该类功能是通过:=
符号实现。
- 选择列
<- data.table(col1=1:10,col2=letters[1:10],col3=LETTERS[1:10],col4=1:10)
dt
dt[,.(col1,col2)]#> col1 col2
#> 1: 1 a
#> 2: 2 b
#> 3: 3 c
#> 4: 4 d
#> 5: 5 e
#> 6: 6 f
#> 7: 7 g
#> 8: 8 h
#> 9: 9 i
#> 10: 10 j
# same above
list(col1,col2)]
dt[,#> col1 col2
#> 1: 1 a
#> 2: 2 b
#> 3: 3 c
#> 4: 4 d
#> 5: 5 e
#> 6: 6 f
#> 7: 7 g
#> 8: 8 h
#> 9: 9 i
#> 10: 10 j
- 新增列
如下所示:新增addcol列,最后的[]是为了显示新增列的数据框,可不增加。
#data.table()函数创建data.table数据框
<- data.table(col1=1:10,col2=letters[1:10],col3=LETTERS[1:10],col4=1:10)
dt # 新增列 :=
:=rep('新列',10)][] #最后的[]是为了显示新增列的数据框,可不增加
dt[,addcol#> col1 col2 col3 col4 addcol
#> 1: 1 a A 1 新列
#> 2: 2 b B 2 新列
#> 3: 3 c C 3 新列
#> 4: 4 d D 4 新列
#> 5: 5 e E 5 新列
#> 6: 6 f F 6 新列
#> 7: 7 g G 7 新列
#> 8: 8 h H 8 新列
#> 9: 9 i I 9 新列
#> 10: 10 j J 10 新列
#dt[,addcol:=rep('新列',10)] 不会显示返回结果,加上[]会显示返回
# 新增多列
`:=`(newcol1=rep('newcol1',10),newcol2=rep('newcol2',10))][]
dt[,#> col1 col2 col3 col4 addcol newcol1 newcol2
#> 1: 1 a A 1 新列 newcol1 newcol2
#> 2: 2 b B 2 新列 newcol1 newcol2
#> 3: 3 c C 3 新列 newcol1 newcol2
#> 4: 4 d D 4 新列 newcol1 newcol2
#> 5: 5 e E 5 新列 newcol1 newcol2
#> 6: 6 f F 6 新列 newcol1 newcol2
#> 7: 7 g G 7 新列 newcol1 newcol2
#> 8: 8 h H 8 新列 newcol1 newcol2
#> 9: 9 i I 9 新列 newcol1 newcol2
#> 10: 10 j J 10 新列 newcol1 newcol2
- 删除列
删除列即将列赋值NULL即可
# 删除列
:=NULL][]
dt[,col1#> col2 col3 col4 addcol newcol1 newcol2
#> 1: a A 1 新列 newcol1 newcol2
#> 2: b B 2 新列 newcol1 newcol2
#> 3: c C 3 新列 newcol1 newcol2
#> 4: d D 4 新列 newcol1 newcol2
#> 5: e E 5 新列 newcol1 newcol2
#> 6: f F 6 新列 newcol1 newcol2
#> 7: g G 7 新列 newcol1 newcol2
#> 8: h H 8 新列 newcol1 newcol2
#> 9: i I 9 新列 newcol1 newcol2
#> 10: j J 10 新列 newcol1 newcol2
# 删除多列
c('newcol1','newcol2'):=NULL][]
dt[,#> col2 col3 col4 addcol
#> 1: a A 1 新列
#> 2: b B 2 新列
#> 3: c C 3 新列
#> 4: d D 4 新列
#> 5: e E 5 新列
#> 6: f F 6 新列
#> 7: g G 7 新列
#> 8: h H 8 新列
#> 9: i I 9 新列
#> 10: j J 10 新列
- 更新
更新即重新赋值,将现有列参与计算等于是重新赋值,可以看成是更新列。
# 更新列
:=11:20][]
dt[,col1#> col2 col3 col4 addcol col1
#> 1: a A 1 新列 11
#> 2: b B 2 新列 12
#> 3: c C 3 新列 13
#> 4: d D 4 新列 14
#> 5: e E 5 新列 15
#> 6: f F 6 新列 16
#> 7: g G 7 新列 17
#> 8: h H 8 新列 18
#> 9: i I 9 新列 19
#> 10: j J 10 新列 20
# not run
# 两列间计算 也可以理解为更新
:=col1/col4] dt[,newcol
Note: DT[a > 4, b := c] is different from DT[a > 4][, b := c]
7.2.3 排序
当我们清洗数据时,我们需要将数据框排序,我们可以使用setorder
或setorderv
函数实现排序。函数是data.table
包的函数,比base R 中的order
函数要节省内存。
注意:按照函数文档说法:Note that queries like x[order(.)] are optimised internally to use data.table’s fast order。即x[order(.)]这样的用法会被优化为data.table的排序方法。
set.seed(45L)
= data.table(A=sample(3, 10, TRUE),
DT B=sample(letters[1:3], 10, TRUE), C=sample(10))
setorder(DT, A, -B) #将DT按照A、B排序 A 升序,-B降序
# 和上面同样的效果 但是函数变成 setorderv
setorderv(DT, c("A", "B"), c(1, -1))