在Rollapply或apply.rolling中应用/ Plyr之类的功能,而不会影响性能

时间:2011-11-25 20:55:13

标签: r

我想在非时间序列数据上使用roll apply like功能,但是在滚动窗口上计算。所以没有必要将它转换为zoo对象并再次返回。有没有办法可以在非常大的数据集上完成?

修改

我正在使用

rollapply(zoo(SPYTS[, "Close"]), 2, function(x) x[1] + x[2], fill=0, align="right") 

关于100万个数据点。这使得从不接缝停止计算。像

这样的东西
SPYTS$LnReturns <- (rbind(0, as.data.frame(log(SPYTS[1:(nrow(SPYTS) - 1), "Close"] / SPYTS[2:nrow(SPYTS), "Close"])))) 

只需几秒钟。

函数function(x) x[1] + x[2]只是一个占位符。我想到的实际功能略有不同。

1 个答案:

答案 0 :(得分:5)

这个答案是我之前删除的评论的扩展版本。

zoo的rollapply已经支持普通向量和矩阵。此外,它的rollapply例程在动作之前从动物园对象中提取普通向量或矩阵,因此动物园对象没有理由比非动物园对象长得多。您观察到的缓慢是rollapply中的错误(提取未正确进行),该错误已于11月初在开发版本中修复。这个版本在R-Forge上,安装方式如下:

install.packages("zoo", repo = "http://r-forge.r-project.org")

另一方面,rollapply的一般性意味着它比特殊用途例程或矢量化操作要慢得多。

动物园确实有一些rollapplyrollmeanrollmedianrollmax)的特殊版本,这些版本针对特定操作进行了优化,速度会快得多。如果你可以制造那些东西,例如滚动平均值的滚动总和与滚动平均值的k相同,那么您可以获得大幅加速。更快的是通过+等简单操作制造滚动结果。

该帖子表明所讨论的功能只是一个例子,但特定功能可以在速度方面产生很大的不同,因为它会影响所讨论的加速类型是否可用。

例如,运行每个rollapply2 * rollmean的3次复制以及一个简单的矢量化加法显示:

> library(zoo)
> library(rbenchmark)
> n <- 10^4
> set.seed(123)
> a <- rnorm(n)
> library(rbenchmark)
> benchmark(rollapply = a1 <- rollapplyr(a, 2, sum, fill = 0),
+    rollmean = a2 <- 2 * rollmeanr(a, 2, fill = 0),
+    add = a3 <- c(0, a[-1] + a[-n]), replications = 3, order = "relative")
       test replications elapsed relative user.self sys.self user.child sys.child
3       add            3    0.00  0.00000      0.00        0         NA        NA
2  rollmean            3    0.07  1.00000      0.08        0         NA        NA
1 rollapply            3    1.85 26.42857      1.84        0         NA        NA
> 
> all.equal(a1, a2)
[1] TRUE
> all.equal(a1, a3)
[1] TRUE