提高选择子集的性能
# 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
,重要的是要注意组合数量变得太大。