Этот ответ является расширенной версией моих предыдущих комментариев, которые я сейчас удалил.
zoo's rollapply
уже поддерживает простые векторы и матрицы.Кроме того, его подпрограмма rollapply
извлекает простые векторы или матрицы из объекта зоопарка перед тем, как с ним работать, поэтому нет никаких причин для того, чтобы объект зоопарка занимал значительно больше времени, чем объект не из зоопарка.Замедление, которое вы наблюдали, было ошибкой в rollapply
(извлечение происходило неправильно), которая была исправлена в начале ноября в версии для разработчиков.Эта версия находится в R-Forge и устанавливается следующим образом:
install.packages("zoo", repo = "http://r-forge.r-project.org")
С другой стороны, общность rollapply
означает, что она будет намного медленнее, чем процедуры специального назначения или векторизованные операции.
zoo действительно имеет некоторые специализированные версии rollapply
(rollmean
, rollmedian
, rollmax
), которые оптимизированы для определенных операций и будут намного быстрее.Если вы можете изготовить что-то из них, например, скользящая сумма k членов равна k
умноженному на среднее значение, то вы можете получить существенное ускорение.Еще быстрее будет производиться результат прокатки из простых операций, таких как +
.
. В сообщении указывалось, что рассматриваемая функция является лишь примером, но конкретная функция может иметь большое значение с точки зрения скорости, поскольку онабудет влиять на то, доступны ли обсуждаемые виды ускорений.
Например, при запуске 3 репликаций каждого из rollapply
, 2 * rollmean
и простое векторизованное добавление показывает это:
> 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