【问题标题】:Implementing a rolling window using data.table使用 data.table 实现滚动窗口
【发布时间】:2017-02-09 00:17:38
【问题描述】:

我可以通过反复“移动”我的数据,然后“逐行”汇总来实现滚动窗口,但这似乎很麻烦,并且不容易推广到不同的窗口大小。

#' Generate dummy data
library(data.table)
set.seed(42)
d <- data.table(id=rep(letters[1:2], each=5), time=rep(1:5,times=2), x=sample.int(10,10,replace=T))

数据如下:

id  time    x
a   1   10
a   2   10
a   3   3
a   4   9
a   5   7
b   1   6
b   2   8
b   3   2
b   4   7
b   5   8

现在在过去 2 次中取一个滚动的“最大值”(对于每个 id)。

#' Now you want to take the maximum of the previous 2 x values (by id)
#' I can do this by creating shifted lagged versions
d[, x.L1 := shift(x,1,type='lag'), by=id]
d[, x.L2 := shift(x,2,type='lag'), by=id]
d[, x.roll.max := max(x,x.L1,x.L2, na.rm=2), by=.(id,time)]

生成这个

id  time    x   x.L1    x.L2    x.roll.max
a   1   10  NA  NA  10
a   2   10  10  NA  10
a   3   3   10  10  10
a   4   9   3   10  10
a   5   7   9   3   9
b   1   6   NA  NA  6
b   2   8   6   NA  8
b   3   2   8   6   8
b   4   7   2   8   8
b   5   8   7   2   8

我假设有更好的方法。

【问题讨论】:

  • 也许可以看看 zooRcppRoll 包中的各种 roll* 函数。
  • @JoshO'Brien:抱歉,固定数据。我看过使用 zoo 和 RcppRoll 的帖子,但有点认为这应该在 data.table 中运行良好。
  • 您的代码简化为 d[, do.call(pmax, c(shift(x, 0:2, type='lag'), na.rm=TRUE)), by=id],但我想这仍然不如 RcppRoll 之类的专用滚筒效率。
  • @Frank:谢谢 - 在下面实现了你的后一个建议

标签: r data.table


【解决方案1】:

所以我按照上面的@Franks 建议去了 RcppRoll。

library(Rcpp)
d[, x.roll.max := roll_max(x, n=2L, align='right', fill=NA, na.rm=T), by=id]

而且我想我不应该尝试在 data.table b/c 中完成这一切,这非常有效。

  id    time    x   x.roll.max
a   1   11  NA
a   2   12  12
a   3   4   12
a   4   10  10
a   5   8   10
a   6   7   8
b   1   9   NA
b   2   2   9
b   3   8   8
b   4   9   9
b   5   6   9
b   6   9   9

【讨论】:

  • 注意首先调用library(Rcpp),因为我收到以下错误function 'enterRNGScope' not provided by package 'Rcpp',我认为这意味着来自Rcpp 的函数被?data.table 屏蔽(参见stackoverflow.com/questions/21657575/…
【解决方案2】:

截至data.table v1.12.4(2019 年 10 月 3 日),用于滚动计算任意 R 函数的函数 frollapply 可用:

library(data.table)

set.seed(42)
d <- data.table(id = rep(letters[1:2], each = 5), time = rep(1:5, times = 2), x = sample.int(10, 10, replace = T))
d[, x.roll.max := frollapply(x = x, n = 2, max, fill = NA, align = "right", na.rm = TRUE), by = id]

    id time  x x.roll.max
 1:  a    1  1         NA
 2:  a    2  5          5
 3:  a    3  1          5
 4:  a    4  9          9
 5:  a    5 10         10
 6:  b    1  4         NA
 7:  b    2  2          4
 8:  b    3 10         10
 9:  b    4  1         10
10:  b    5  8          8

【讨论】:

    【解决方案3】:

    我喜欢 Ulrich 的 TTR 包。下面给你一个跑步最大值

    TTR::runMax(d$x,2)
    

    【讨论】:

    • 关于 TTR 的好消息,它运行良好,但(不幸的是)不处理缺失值(没有 na.rm=T 选项)
    猜你喜欢
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2020-08-13
    • 2016-11-19
    • 2012-07-25
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多