二级索引和自动索引

1.二级指标

a.什么是二级指标?

二级指标类似于key在data.table中的作用,但是两者主要有如下差别:

  •  它不会对整个data.table进行排序,而是只对当列排序,并将此列存储在属性中index指标中。
  • data.table中可以有多个二级指标

b.设置和得到二级指标

> setindex(flights, origin)
> head(flights)[,-c(1:6)]

   arr_delay cancelled carrier tailnum flight origin dest air_time distance hour min
1:        13         0      AA  N338AA      1    JFK  LAX      359     2475    9  14
2:        13         0      AA  N335AA      3    JFK  LAX      363     2475   11  57
3:         9         0      AA  N327AA     21    JFK  LAX      351     2475   19   2
4:       -26         0      AA  N3EHAA     29    LGA  PBI      157     1035    7  22
5:         1         0      AA  N319AA    117    JFK  LAX      350     2475   13  47
6:         0         0      AA  N3DEAA    119    EWR  LAX      339     2454   18  24

 

也可以使用: setindexv(flights, "origin")  #在编程汇总,这种方法非常有用,第一种方法在交互模式下比较方便

 

> names(attributes(flights))
[1] "names"             "row.names"         "class"             ".internal.selfref" "index"  

 

  • setindex()setindexv()都能在data.table中添加二级指数
  • 使用二级指标后,flights并没有进行升序排列,而key方法则会进行升序排列
  • flights属性index已经添加了origin
  • setindex(flights,NULL)可以清除所有的二级指标

 

如何显示到目前为止flights所有的二级指标?

> indices(flights)
[1] "hour"   "origin"
> setindex(flights, origin, dest)
> indices(flights)

[1] "hour"         "origin"       "origin__dest"

 

  • 函数indices()返回目前为止filghts中所有的二级指标,如果没有,则返回NULL
  • 设置新的二级指标,先前的二级指标并不会丢失,而是可以有多个二级指标

 

c)为什么我们需要二级指标?

考虑一个问题,假设我们需要设置一个主键“origin”,并寻找主键值等于“JFK”的所有行:

> setkey(flights, origin)
> flights["JFK"][,-c(1:6)] # or flights[.("JFK")]

setkey()存在的问题是:寻找匹配的行,其算法并不浪费时间,浪费时间的是对整个数据集进行排序的过程。如果再寻找另一个指标的值,则需要重新设置主键,排序并查找。我们需要的是不用重新排序,就能查找到所需的数据。

 

为什么是二级指标?因为二级指标可以设置多个,且已经存储在属性中index下,所以如果需要计算的话,可以直接调用,而不需要再重新对整个data.table进行升序排序。

 

新参数“on”拥有简洁的语法,并自动建立和使用二级指标。

 

on参数:

  • 使用二级指标提取子集,可以快到飞起来,而且不必每次都设置setkey()
  • 每次使用时,只需要检查属性下的index
  • 语法简洁,可读性强,在key中,也建议使用on

 

2.on参数和二级指标在快速提取子集上的应用

 

a.在“j”上快速提取

在没有设置二级指标的情况下,

> flights["JFK", on = "origin"]

## alternatively

# flights[.("JFK"), on = "origin"] (or)

# flights[list("JFK"), on = "origin"]

此结果运行速度较慢,且观察数据结构如下:

> names(attributes(flights))
[1] "names"             "row.names"         "class"             ".internal.selfref" "sorted"          
> str(attributes(flights))
List of 5
 $ names            : chr [1:17] "year" "month" "day" "dep_time" ...
 $ row.names        : int [1:253316] 1 2 3 4 5 6 7 8 9 10 ...
 $ class            : chr [1:2] "data.table" "data.frame"
 $ .internal.selfref:<externalptr>
 $ sorted           : chr "origin"

运行结果后,不会保存为属性index.此方法并不推荐

 

提前设置好二级指标,然后执行以下代码:

> setindex(flights, origin)
> flights["JFK", on = "origin", verbose = TRUE][1:5]

on= matches existing key, using key
Starting bmerge ...done in 0 secs

筛选两个匹配指标:

> flights[.("JFK", "LAX"), on = c("origin", "dest")][1:5]
   year month day dep_time dep_delay arr_time arr_delay cancelled carrier tailnum flight origin dest air_time distance hour min
1: 2014     1   1      914        14     1238        13         0      AA  N338AA      1    JFK  LAX      359     2475    2: 2014     1   1     1157        -3     1523        13         0      AA  N335AA      3    JFK  LAX      363     2475   3: 2014     1   1     1902         2     2224         9         0      AA  N327AA     21    JFK  LAX      351     2475   4: 2014     1   1     1347         2     1706         1         0      AA  N319AA    117    JFK  LAX      350     2475   5: 2014     1   1     2133        -2       37       -18         0      AA  N323AA    185    JFK  LAX      338     2475  

 

b.在“j”上进行选择

以下的操作与keys部分相似,唯一不同的多了参数“on”。原来是用key来限制的,现在是用on.

> 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

 

c.链接

排序

> 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

 

d. 在“j”上计算

计算最大值

> flights[.("LGA","TPA"),max(arr_delay),on=c("origin","dest")]
[1] 486

 

e. 替换

> 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 23
> flights[.(23L), hour := 0L, on = "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

f. 用“by”分组汇总

> ans <- flights["JFK", max(dep_delay), keyby = month, on = "origin"]
> head(ans)

   month   V1
1:     1  881
2:     1 1014
3:     1  920
4:     1 1241
5:     1  853
6:     1  798

月份为什么都是1?

 

g. mult参数

> flights[c("BOS", "DAY"), on = "dest", mult = "first"]
   year month day dep_time dep_delay arr_time arr_delay cancelled carrier tailnum flight origin dest air_time distance 1: 2014     1   1     1155        -5     1253       -11         0      B6  N368JB   2380    EWR  BOS       45      200   2: 2014     1   1     1732        25     1945        35         0      EV  N13968   3806    EWR  DAY      102      533  

 

> flights[.(c("LGA", "JFK", "EWR"), "XNA"), on = c("origin", "dest"), mult = "last"]
   year month day dep_time dep_delay arr_time arr_delay cancelled carrier tailnum flight origin dest air_time distance 1: 2014    10  31      625        -5      829       -11         0      MQ  N501MQ   3547    LGA  XNA      165     1147   
2:   NA    NA  NA       NA        NA       NA        NA        NA      NA      NA     NA    JFK  XNA       NA       NA  
3: 2014    10  31      634        -2      834       -25         0      EV  N17138   4419    EWR  XNA      160     1131   

 

h. nomatch参数

> flights[.(c("LGA", "JFK", "EWR"), "XNA"), mult = "last", on = c("origin", "dest"), nomatch = 0L]
   year month day dep_time dep_delay arr_time arr_delay cancelled carrier tailnum flight origin dest air_time distance
1: 2014    10  31      625        -5      829       -11         0      MQ  N501MQ   3547    LGA  XNA      165     1147   
2: 2014    10  31      634        -2      834       -25         0      EV  N17138   4419    EWR  XNA      160     1131   

 

3.自动添加指标

> set.seed(1L)
> dt = data.table(x = sample(1e5L, 1e7L, TRUE), y = runif(100L))
> print(object.size(dt), units = "Mb")

114.4 Mb

当我们第一次对某列使用“==”或“%in%”后,此列就会自动加入属性index中,

> names(attributes(dt))
[1] "names"             "row.names"         "class"             ".internal.selfref"
> (t1 <- system.time(ans <- dt[x == 989L]))
用户 系统 流逝
0.56 0.06 0.72
> head(ans)
     x         y
1: 989 0.5372007
2: 989 0.5642786
3: 989 0.7151100
4: 989 0.3920405
5: 989 0.9547465
6: 989 0.2914710
> names(attributes(dt))
[1] "names"             "row.names"         "class"             ".internal.selfref" "index"           
> indices(dt)
[1] "x"

 

再一次进行查询上述语句,

> (t2 <- system.time(dt[x == 989L]))
用户 系统 流逝
> system.time(dt[x %in% 1989:2012])
用户 系统 流逝
0.00 0.00 0.07

 

原来是时间是0.72.现在是0.07,速度有了很大的提高。

 

如果不想自动添加二级指标,可以提前设置:options(datatable.auto.index = FALSE)

自动添加指标失效后,还可以用setindex()\setindexv()来设置,如果想全部禁用二级指标,可以设置:

options(datatable.use.index = FALSE)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值