Применить / Plyr, как функциональность без ущерба для производительности в Rollapply или apply.rolling - PullRequest
2 голосов
/ 26 ноября 2011

Я хочу использовать функцию «применить по-другому», как функциональность к данным, не относящимся к временным рядам, но вычисляемым на скользящем окне. Поэтому нет необходимости превращать его в зоопарк и обратно. Есть ли способ сделать это на очень большом наборе данных?

Редактировать

Я использую

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

на 1 миллион точек данных. Это никогда не требует швов, чтобы прекратить расчет. Что-то вроде

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 Ответ

5 голосов
/ 26 ноября 2011

Этот ответ является расширенной версией моих предыдущих комментариев, которые я сейчас удалил.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...