6 min read

data.table学习笔记2

  • data.table的特点:减小计算复杂度,降低计算时间
  • 这一部分笔记主要讲述如何更新数据集,而不产生新的数据拷贝。
  • 主要用到的符号是“:=”,类似于指针功能,通过引用更新列。
  • 本章的操作,实际上是把data.table作为一个数据库在操作。

1.语义引用

:=两种用法:

左右相等方式

DT[, c("colA", "colB", ...) := list(valA, valB, ...)]

# when you have only one column to assign to you 
# can drop the quotes and list(), for convenience
DT[, colA := valA]

函数方式

DT[, `:=`(colA = valA, # valA is assigned to colA
      colB = valB, # valB is assigned to colB
      ...
)]
  • 左右相等方式比较容易编码,特别是,事先不知道需要被赋值的列的时候。
  • 相对而言,函数方式更加趁手,可以少写代码。
  • 操作符“:=”没有返回值。
  • 既然参数j里面可以使用操作符“:=”,那么,就像上一讲中学习到的内容,我们可以和参数i和参数by一起,做些聚合的运算

2. 添加/更新/删除列

2.1 添加列

增加两列,计算航班的速度和延迟时间。注意,“:==”不返回任何值,为了方便查看,加入[]

flights[,":="(speed = distance / (air_time / 60),delay = arr_delay+dep_delay)][]
##         year month day dep_time dep_delay arr_time arr_delay cancelled
##      1: 2014     1   1      914        14     1238        13         0
##      2: 2014     1   1     1157        -3     1523        13         0
##      3: 2014     1   1     1902         2     2224         9         0
##      4: 2014     1   1      722        -8     1014       -26         0
##      5: 2014     1   1     1347         2     1706         1         0
##     ---                                                               
## 253312: 2014    10  31     1459         1     1747       -30         0
## 253313: 2014    10  31      854        -5     1147       -14         0
## 253314: 2014    10  31     1102        -8     1311        16         0
## 253315: 2014    10  31     1106        -4     1325        15         0
## 253316: 2014    10  31      824        -5     1045         1         0
##         carrier tailnum flight origin dest air_time distance hour min
##      1:      AA  N338AA      1    JFK  LAX      359     2475    9  14
##      2:      AA  N335AA      3    JFK  LAX      363     2475   11  57
##      3:      AA  N327AA     21    JFK  LAX      351     2475   19   2
##      4:      AA  N3EHAA     29    LGA  PBI      157     1035    7  22
##      5:      AA  N319AA    117    JFK  LAX      350     2475   13  47
##     ---                                                              
## 253312:      UA  N23708   1744    LGA  IAH      201     1416   14  59
## 253313:      UA  N33132   1758    EWR  IAH      189     1400    8  54
## 253314:      MQ  N827MQ   3591    LGA  RDU       83      431   11   2
## 253315:      MQ  N511MQ   3592    LGA  DTW       75      502   11   6
## 253316:      MQ  N813MQ   3599    LGA  SDF      110      659    8  24
##            speed delay
##      1: 413.6490    27
##      2: 409.0909    10
##      3: 423.0769    11
##      4: 395.5414   -34
##      5: 424.2857     3
##     ---               
## 253312: 422.6866   -29
## 253313: 444.4444   -19
## 253314: 311.5663     8
## 253315: 401.6000    11
## 253316: 359.4545    -4

2.2 更新列

观察 fligths 里的 hour列。

flights[,sort(unique(hour))]
##  [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
## [24] 23 24

0和24同时存在,二者其实是等同的。因此,可以把24换为0。

flights[hour == 24L,hour := 0L]
flights[,sort(unique(hour))]
##  [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
## [24] 23

2.3删除列

譬如删除speed列

flights[,speed := NULL,]
str(flights)
## Classes 'data.table' and 'data.frame':   253316 obs. of  18 variables:
##  $ year     : int  2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 ...
##  $ month    : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ day      : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time : int  914 1157 1902 722 1347 1824 2133 1542 1509 1848 ...
##  $ dep_delay: int  14 -3 2 -8 2 4 -2 -3 -1 -2 ...
##  $ arr_time : int  1238 1523 2224 1014 1706 2145 37 1906 1828 2206 ...
##  $ arr_delay: int  13 13 9 -26 1 0 -18 -14 -17 -14 ...
##  $ cancelled: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ carrier  : chr  "AA" "AA" "AA" "AA" ...
##  $ tailnum  : chr  "N338AA" "N335AA" "N327AA" "N3EHAA" ...
##  $ flight   : int  1 3 21 29 117 119 185 133 145 235 ...
##  $ origin   : chr  "JFK" "JFK" "JFK" "LGA" ...
##  $ dest     : chr  "LAX" "LAX" "LAX" "PBI" ...
##  $ air_time : int  359 363 351 157 350 339 338 356 161 349 ...
##  $ distance : int  2475 2475 2475 1035 2475 2454 2475 2475 1089 2422 ...
##  $ hour     : int  9 11 19 7 13 18 21 15 15 18 ...
##  $ min      : int  14 57 2 22 47 24 33 42 9 48 ...
##  $ delay    : int  27 10 11 -34 3 4 -20 -17 -18 -16 ...
##  - attr(*, ".internal.selfref")=<externalptr> 
##  - attr(*, "index")= int

3.在分组的情况下使用“:=”

感觉分组情况下,就地更新列,并不符合常规。这样对数据集的改动太大了。这里其实不是我理解的意思是,并不是用分组后的统计结果替代原数据集。而是根据分组统计后的结果,更新列。 譬如,从origin到dest,延迟时间最长为多少?

flights[, max_delay_time := max(dep_delay+arr_delay), keyby=.(origin, dest)]
head(flights)
##    year month day dep_time dep_delay arr_time arr_delay cancelled carrier
## 1: 2014     1   2      724        -2      810       -25         0      EV
## 2: 2014     1   3     2313        88        9        79         0      EV
## 3: 2014     1   4     1526       220     1618       211         0      EV
## 4: 2014     1   4      755        35      848        19         0      EV
## 5: 2014     1   5      817        47      921        42         0      EV
## 6: 2014     1   5     2301        66        2        62         0      EV
##    tailnum flight origin dest air_time distance hour min delay
## 1:  N11547   4373    EWR  ALB       30      143    7  24   -27
## 2:  N18120   4470    EWR  ALB       29      143   23  13   167
## 3:  N11184   4373    EWR  ALB       32      143   15  26   431
## 4:  N14905   4551    EWR  ALB       32      143    7  55    54
## 5:  N19966   4470    EWR  ALB       26      143    8  17    89
## 6:  N19966   4682    EWR  ALB       31      143   23   1   128
##    max_delay_time
## 1:            618
## 2:            618
## 3:            618
## 4:            618
## 5:            618
## 6:            618

从结果可以看到,新增加了一列max_delay_time,而且从EWR-ALB区间,该列值为618,为最大值。

4. 对多列数据进行操作

添加了两列:统计每个月,最长的出发延迟时间、到达延迟时间

in_cols  = c("dep_delay", "arr_delay")
out_cols = c("max_dep_delay", "max_arr_delay")
flights[, c(out_cols) := lapply(.SD, max), by = month, .SDcols = in_cols]
head(flights)
##    year month day dep_time dep_delay arr_time arr_delay cancelled carrier
## 1: 2014     1   2      724        -2      810       -25         0      EV
## 2: 2014     1   3     2313        88        9        79         0      EV
## 3: 2014     1   4     1526       220     1618       211         0      EV
## 4: 2014     1   4      755        35      848        19         0      EV
## 5: 2014     1   5      817        47      921        42         0      EV
## 6: 2014     1   5     2301        66        2        62         0      EV
##    tailnum flight origin dest air_time distance hour min delay
## 1:  N11547   4373    EWR  ALB       30      143    7  24   -27
## 2:  N18120   4470    EWR  ALB       29      143   23  13   167
## 3:  N11184   4373    EWR  ALB       32      143   15  26   431
## 4:  N14905   4551    EWR  ALB       32      143    7  55    54
## 5:  N19966   4470    EWR  ALB       26      143    8  17    89
## 6:  N19966   4682    EWR  ALB       31      143   23   1   128
##    max_delay_time max_dep_delay max_arr_delay
## 1:            618           973           996
## 2:            618           973           996
## 3:            618           973           996
## 4:            618           973           996
## 5:            618           973           996
## 6:            618           973           996

另外一种形式

flights[,c("max_dep_delay", "max_arr_delay") := lapply(.SD, max),.SDcols = c("dep_delay", "arr_delay")]