Rでローリング計算するならrollifyが便利

私は業務でよくRを使います。

今回はRでローリング計算する際に重宝する「tibbletime」と呼ばれるパッケージに含まれる「rollify」と呼ばれる関数について紹介したいと思います。
「rollify」はローリング計算において非常に自由度が高く使い勝手が良いです。
「dplyr」にも「RcppRoll」と呼ばれる素晴らしい関数があるのですが、
敢えて「rollify」を使う理由は

  • ローリング計算に与える関数を自作できる
  • dplyrとの相性が良い

という点です。

それでは実際に「rollify」を使ってみます!
「rollify」を使用するには下記のように「tibbletime」と呼ばれるパッケージをロードします。

library(tidyverse)
library(tibbletime)

今回は「airquality」と呼ばれるRの標準データセットを用います。
「airquality」はニューヨークの大気状態観測のデータです。

Ozone オゾン量
Solar.R 日射量
Wind 風力
Temp 温度
Month Day 月のうちの日
 airquality %>% head(3)
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3

ざっと各変数の関係を可視化してみます

airquality %>% select(-Month, -Day) %>% pairs(panel=panel.smooth)

f:id:k-bind:20190910232505p:plain
airqualityのデータ

例えばこのデータの「Ozone」と「Wind」の30日間ローリングで相関係数を求めたいとしましょう。
その場合は予め「rollify」に関数を定義します。windowにはローリング期間を入力します(今回は30日なので"30"と入力しました)。

cor_roll_30d <- rollify(~cor(.x, .y), window = 30)

あとはdplyrのmutate文に定義した関数を使うだけ!

df_roll30_ozone_wind <-
  airquality %>%
  select(Ozone, Wind) %>% 
  drop_na() %>% # 相関係数が正しく計算できるようにNAを除いている
  mutate(cor_30d = cor_roll_30d(Ozone, Wind))

一応結果を可視化してみます

df_roll30_ozone_wind %>% 
ggplot(aes(x = rep(1:nrow(df_roll30_ozone_wind)), y = cor_30d)) + 
geom_line() + xlab("日数") + ylab("相関係数 (OzoneとWind)")

f:id:k-bind:20190910235519p:plain

このように非常に簡単にローリング計算を行うことが出来ます。
関数を自作することが出来るので2変数以上組み合わせた複雑なローリング計算等も実行可能です。

avg_of_avgs <- rollify(function(x, y, z) {
(mean(x) + mean(y) + mean(z)) / 3}, window = 3)

airquality %>%
  select(Ozone, Wind, Temp) %>%
  drop_na() %>% 
  mutate(ave_3val = avg_of_avgs(Ozone, Wind, Temp)) %>% 
  head(5)

  Ozone Wind Temp ave_3val
1    41  7.4   67       NA
2    36  8.0   72       NA
3    12 12.6   74 36.66667
4    18 11.5   62 34.01111
5    28 14.9   66 33.22222

オフィシャルドキュメントはこちら
https://cran.r-project.org/web/packages/tibbletime/tibbletime.pdf