7.2 常规操作

7.2.1 行筛选

上文已经大致讲过行筛选,但是行筛选使用有一定的技巧,涉及到运算的快慢。主要是逻辑条件的设置,交集并集之间的差异。除了上文中的关系运算筛选,逻辑运算筛选除外,data.table中还有几个常用的筛选函数。

  • 数字向量筛选

%in%用法与 sql 中 in 用法类似。

# 筛选 %in% 
flights[ hour %in% seq(1,24,2) ]
  • 字符向量筛选

%chin%用法与 %in% 类似,但仅仅针对字符。

# 字符筛选
flights[ origin %chin% c('JFK','LGA')]
# not run 同上 %chin% 对字符速度筛选速度更快
#flights[ origin %in% c('JFK','LGA')]
  • between 筛选

该函数的新特性矢量化挺实用。

#between 函数参数
#between(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
X <-  data.table(a=1:5, b=6:10, c=c(5:1))
X[b %between% c(7,9)]
#>    a b c
#> 1: 2 7 4
#> 2: 3 8 3
#> 3: 4 9 2
X[between(b, 7, 9)] #效果同上
#>    a b c
#> 1: 2 7 4
#> 2: 3 8 3
#> 3: 4 9 2
X[c %between% list(a,b)] # 矢量化
#>    a b c
#> 1: 1 6 5
#> 2: 2 7 4
#> 3: 3 8 3
  • like 筛选

%like% 用法与SQL中 like 类似。

# %like% 用法与SQL中 like 类似
DT = data.table(Name=c("Mary","George","Martha"), Salary=c(2,3,4))
DT[Name %like% "^Mar"]
#>      Name Salary
#> 1:   Mary      2
#> 2: Martha      4

7.2.2 新增更新列

新增或删除或更新列是我们数据清洗过程中的常规操作,data.table中实现该类功能是通过:=符号实现。

  • 选择列
dt <- data.table(col1=1:10,col2=letters[1:10],col3=LETTERS[1:10],col4=1:10)
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
dt[,list(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
  • 新增列

如下所示:新增addcol列,最后的[]是为了显示新增列的数据框,可不增加。

#data.table()函数创建data.table数据框
dt <- data.table(col1=1:10,col2=letters[1:10],col3=LETTERS[1:10],col4=1:10)
# 新增列 :=
dt[,addcol:=rep('新列',10)][] #最后的[]是为了显示新增列的数据框,可不增加
#>     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)] 不会显示返回结果,加上[]会显示返回
# 新增多列
dt[,`:=`(newcol1=rep('newcol1',10),newcol2=rep('newcol2',10))][]
#>     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即可

# 删除列
dt[,col1:=NULL][]
#>     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
# 删除多列
dt[,c('newcol1','newcol2'):=NULL][]
#>     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   新列
  • 更新

更新即重新赋值,将现有列参与计算等于是重新赋值,可以看成是更新列。

# 更新列
dt[,col1:=11:20][]
#>     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 
# 两列间计算 也可以理解为更新
dt[,newcol:=col1/col4]

Note: DT[a > 4, b := c] is different from DT[a > 4][, b := c]

7.2.3 排序

当我们清洗数据时,我们需要将数据框排序,我们可以使用setordersetorderv函数实现排序。函数是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)
DT = data.table(A=sample(3, 10, TRUE),
         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))