数据表中的shift()在v1.9.6版本中对于许多组而言速度较慢。

7
感谢您首先在dt1.9.6中实现了shift。 当我有许多不同的组时,shift()比我的旧代码慢得出乎意料。
library(data.table)
library(microbenchmark)
set.seed(1)
mg <- data.table(expand.grid(year = 2012:2016, id = 1:1000),
                 value = rnorm(5000))
microbenchmark(dt194 = mg[, l1 := c(value[-1], NA), by = .(id)],
           dt196 = mg[, l2 := shift(value, n = 1,
                               type = "lead"), by = .(id)])
## Unit: milliseconds
##   expr      min        lq      mean    median       uq        max  eval
##  dt194  4.93735  5.236034  5.718654  5.623736  5.74395   9.555922   100
##  dt196 83.92612 87.530404 91.700317 90.953947 91.43783 257.473242   100

这里有一个详细的脚本:https://github.com/nachti/datatable_test/blob/master/leadtest.R 我是否误用了 shift()
编辑:避免使用 := 也没有帮助 (@MichaelChirico):
microbenchmark(dt194 = mg[, c(value[-1], NA), by = id],
               dt196 = mg[, shift(value, n = 1,
                                   type = "lead"), by = id])

## Unit: milliseconds
##   expr       min        lq     mean    median        uq       max neval
##  dt194  5.161973  5.429927  5.78047  5.698263  5.798132  10.42217   100
##  dt196 79.526981 87.914502 92.18144 91.240949 91.896799 266.04031   100

除此之外,使用:=也是任务的一部分...

2
我不认为shift能够超过c(value[-1], NA)是一个合理的期望。虽然可能有改进的潜力,但基本的R解决方案已经被极度优化,而且一个提供更多灵活性的函数(例如非向量输入)必须会更慢。 - Roland
1
@Roland:对于许多组来说,它只是更慢。如果只有几个组(例如2个),shift()会稍微快一些。点击上面的链接查看示例。 - nachti
1
我认为你应该将此问题提交到data.table的错误跟踪器。 - Roland
1
好的。已在此处报告:https://github.com/Rdatatable/data.table/issues/1534 - nachti
1
你不应该在基准测试中使用 `:=`。只需运行 mg[ , c(value[-1L], NA), by = id]mg[ , shift(value, 1, "lead"), id] 即可。 - MichaelChirico
显示剩余3条评论
1个回答

2
data.table 的版本 1.14.3 中,这个问题已经得到了解决,shift 比以往任何时候都更快。
library(data.table)
library(microbenchmark)
set.seed(1)
mg = data.table(expand.grid(year=2012:2016, id=1:1000),
                value=rnorm(5000))
microbenchmark(v1.9.4  = mg[, c(value[-1], NA), by=id],
               v1.9.6  = mg[, shift_no_opt(value, n=1, type="lead"), by=id],
               v1.14.3 = mg[, shift(value, n=1, type="lead"), by=id],
               unit="ms")
# Unit: milliseconds
#     expr     min      lq    mean  median      uq    max neval
#   v1.9.4  3.6600  3.8250  4.4930  4.1720  4.9490 11.700   100
#   v1.9.6 18.5400 19.1800 21.5100 20.6900 23.4200 29.040   100
#  v1.14.3  0.4826  0.5586  0.6586  0.6329  0.7348  1.318   100

感谢实现! - nachti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接