r - 为什么列选择的 data.table 表示法会影响速度

标签 r data.table

速度似乎有所不同,具体取决于您如何指定要从数据中选择的列。表: x[, .(var)]对比 x[, c('var')] .
原因可能很明显,但是在帮助页面.() , list()c()符号似乎可以互换使用。
我使用相当大的数据集,所以这对我来说有点重要:-)

示例(调用顺序不影响速度):

x <- as.data.table(as.character(rnorm(20000000,1,0.5)))
setkey(x, V1)

tic(); x[, .(V1)]; toc()
25.08 sec elapsed


tic(); x[, c('V1')]; toc()
0.28 sec elapsed

tic(); x[, 1]; toc()
0.02 sec elapsed

> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] tictoc_1.0        data.table_1.12.8

loaded via a namespace (and not attached):
[1] compiler_3.6.1  tools_3.6.1     lifecycle_0.2.0 rlang_0.4.6  

最佳答案

您发现了一个错误(问题提交 here)-- data.table正在尝试确定 [] 的输出是否是键控的;为此,它正在运行一个内部 is.sorted功能。这在一个巨大的独特字符串表上非常慢。

幸运的是,我们可以进行静态分析并意识到您的输出表实际上是键控的——没有子集,键列 ( V1 ) 没有变化。因此排序顺序不能改变,您的输出也将按 V1 排序。 .

此逻辑内置于 PR to fix this issue -- 你可以用 remotes::install_github('Rdatatable/data.table@fix_sorting_on_sorted') 测试一下,但需要注意的是,这是该软件包的最新版本,或者您可以等到它合并到 master,或者直到新版本发布到 CRAN。

与此同时,这里有一个解决方法:

setkey(x, NULL)
system.time(x[ , .(V1)])
#    user  system elapsed 
#   0.120   0.087   0.213

当然,这会阻止以后的处理识别您的数据已排序及其效率......

在这种情况下(!仅在这种情况下 - 小心使用!!!) - 您自己确定数据已经按 V1 排序-- 您可以通过以下方式立即恢复 key :
setattr(x, 'sorted', 'V1')

更普遍的是,选择与 [ 之间存在细微差异。 , [[ , $[将往往是最慢的,因为我们做了很多“静态查询分析”来帮助提高您的代码的效率,这伴随着我们希望几乎每次都会很小的性能成本。任何时候这个成本都不小,它应该是一个错误。还有一些工作正在积极进行中尝试提供快捷方式来减少这种开销,例如参见 this PR

关于r - 为什么列选择的 data.table 表示法会影响速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62019120/

相关文章:

r - 如何将字符串向量应用于逻辑向量

使用 fct_relevel 按组对因子重新排序仅更改第一组中的因子顺序

r - 根据列中的其他值填写 NA 值

r - Lapply to all columns in a data.frame 除了一个并替换R中的数据

r - 如何按组获取变量的所有最小值?

r - 选择数据表中的连续列和非连续列,如 dplyr 的 group_by 中

r - 使用 R 尽快计算大型点云的特征值

r - 在R中绘制频率密度直方图

java - h2o - 无法找到或加载主类代码 7 错误

r - 如何使用 data.table 从两个不同的数据框中按 ID 进行汇总