提高选择子集的性能

# example data
set.seed(1)
n  = 1e7
ng = 1e4
DT = data.table(
    g1  = sample(ng, n, replace=TRUE),
    g2  = sample(ng, n, replace=TRUE),
    v  = rnorm(n)
)

匹配一列

第一次使用 ==%in%进行子集化操作后……

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#    0.12    0.03    0.16 

已为 g1 自动创建索引。后续的子集操作几乎立即运行:

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#       0       0       0

要监视创建或使用索引的时间,请添加 verbose=TRUE 选项或更改全局设置 options(datatable.verbose=TRUE)

匹配多列

目前,在两列上匹配不会自动创建索引:

system.time(
    DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
#    user  system elapsed 
#    0.57    0.00    0.57

重新运行它,它将保持缓慢。即使我们使用 setindex(DT, g1, g2) 手动添加索引,它仍将保持缓慢,因为该查询尚未通过包进行优化。

幸运的是,如果我们可以枚举我们想要搜索的值组合并且索引可用,我们可以快速等同连接:

system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#    0.53    0.00    0.54 
setindex(DT, g1, g2)
system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#       0       0       0

对于 CJ,重要的是要注意组合数量变得太大。