二级索引与主键的区别:
* 不在内存中将整个data.table数据集重新排序。它只会计算某列的顺序,将这个顺序向量保存在一个附件的属性index里面。 * 一个data.table可以有多个二级索引。 见下面代码实例。
setindex(flights,origin)
head(flights)
## year month day dep_time dep_delay arr_time arr_delay cancelled carrier
## 1: 2014 1 1 914 14 1238 13 0 AA
## 2: 2014 1 1 1157 -3 1523 13 0 AA
## 3: 2014 1 1 1902 2 2224 9 0 AA
## 4: 2014 1 1 722 -8 1014 -26 0 AA
## 5: 2014 1 1 1347 2 1706 1 0 AA
## 6: 2014 1 1 1824 4 2145 0 0 AA
## tailnum flight origin dest air_time distance hour min
## 1: N338AA 1 JFK LAX 359 2475 9 14
## 2: N335AA 3 JFK LAX 363 2475 11 57
## 3: N327AA 21 JFK LAX 351 2475 19 2
## 4: N3EHAA 29 LGA PBI 157 1035 7 22
## 5: N319AA 117 JFK LAX 350 2475 13 47
## 6: N3DEAA 119 EWR LAX 339 2454 18 24
names(attributes(flights))
## [1] "names" "row.names" "class"
## [4] ".internal.selfref" "index"
indices(flights)
## [1] "origin"
setindex(flights,NULL)
indices(flights)
## NULL
重新创建一个索引
setindex(flights,origin,dest)
indices(flights)
## [1] "origin__dest"
setindex(flights,origin)
提取origin是JFK的所有航班记录:
flights[.("JFK"),on="origin"]
## 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 1347 2 1706 1 0
## 5: 2014 1 1 2133 -2 37 -18 0
## ---
## 81479: 2014 10 31 1705 -4 2024 -21 0
## 81480: 2014 10 31 1827 -2 2133 -37 0
## 81481: 2014 10 31 1753 0 2039 -33 0
## 81482: 2014 10 31 924 -6 1228 -38 0
## 81483: 2014 10 31 1124 -6 1408 -38 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 N319AA 117 JFK LAX 350 2475 13 47
## 5: AA N323AA 185 JFK LAX 338 2475 21 33
## ---
## 81479: UA N596UA 512 JFK SFO 337 2586 17 5
## 81480: UA N568UA 514 JFK SFO 344 2586 18 27
## 81481: UA N518UA 535 JFK LAX 320 2475 17 53
## 81482: UA N512UA 541 JFK SFO 343 2586 9 24
## 81483: UA N590UA 703 JFK LAX 323 2475 11 24
筛选满足条件origin=“LGA” 和dest=“TPA”的数据集,并且只返回arr_delay列。
flights[.("LGA","TPA"),.(arr_delay),on=c("origin","dest")]
## arr_delay
## 1: 1
## 2: 14
## 3: -17
## 4: -4
## 5: -12
## ---
## 1848: 39
## 1849: -24
## 1850: -12
## 1851: 21
## 1852: -11
flights[.("LGA","TPA"),.(arr_delay),on=c("origin","dest")][order(-arr_delay)]
## arr_delay
## 1: 486
## 2: 380
## 3: 351
## 4: 318
## 5: 300
## ---
## 1848: -40
## 1849: -43
## 1850: -46
## 1851: -48
## 1852: -49
找出满足条件origin=“LGA” 和dest=“TPA”的航班记录中,最长到达延误时间。
flights[.("LGA","TPA"),.(MaxArrDelay=max(arr_delay),MinArrDelay=min(arr_delay)),on=c("origin","dest")]
## MaxArrDelay MinArrDelay
## 1: 486 -49
flights[.("JFK"),max(dep_delay),keyby=month,on="origin"]
## month V1
## 1: 1 881
## 2: 1 1014
## 3: 1 920
## 4: 1 1241
## 5: 1 853
## 6: 1 798
## 7: 1 926
## 8: 1 772
## 9: 1 553
## 10: 1 848
是继续使用以前的例子,hour中的24替换为0。
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
flights[.(24L),hour:=0L,on="hour"]
data.table 会默认对==
和%in%
操作符自动创建索引,并且作为data.table的属性保存起来。
首先创建1个非常大的data.table来测试性能。
set.seed(1L)
dt = data.table(x=sample(1e5L,1e7L,TRUE),y=runif(100L))
print(object.size(dt),units = "Mb")
## 114.4 Mb
列出dt的属性。
names(attributes(dt))
## [1] "names" "row.names" "class"
## [4] ".internal.selfref"
第一次使用==
或%in%
时,会自动创建一个二级索引,用来进行subset。
(t1 <- system.time(ans <- dt[x==989L]))
## user system elapsed
## 0.23 0.03 0.27
names(attributes(dt))
## [1] "names" "row.names" "class"
## [4] ".internal.selfref" "index"
重新进行一次subset,由于索引已经创建,速度会很快。
(t2 <- system.time(ans <- dt[x==989L]))
## user system elapsed
## 0 0 0
从两次对比时间,可以看出,第二次时间已经大为缩短。到写这篇博客为止,还没有对>=,<=等符号自动二级索引。
indices(dt)
## [1] "x"
setindex(dt,NULL)
(t3 <- system.time(ans <- dt[x>=989L]))
## user system elapsed
## 0.16 0.03 0.22
indices(dt)
## NULL