Rで移動平均の算出方法

顔妻です。

今回は時系列データの分析でよく使われる移動平均の出し方についてです。移動平均は株価の分析でよく使われると思います。statsパッケージに含まれているfilter関数を利用するのですが、dplyrとかぶりますので、この対処方法もセットでご紹介していきます。

移動平均の計算方法

以下の方法で実現できます。dplyr関数との被りはstats::この記法を加えることで回避することができます。

library(tidyverse)
 theme_set(theme_bw())
 d <- read.csv("https://raw.githubusercontent.com/maruko-rosso/datasciencehenomiti/master/data/ShopSales.csv")

# 移動平均で実施したい範囲
n <- 5

# 移動平均線の作成
 d$date <- as.Date(d$date) d %>% 
   group_by(date) %>% 
   summarise(price = sum(price,na.rm = T)) %>% 
   mutate(
     move_3 = stats::filter(price, rep(1,n) / n, sides = 1), # 過去数値を参照
     move_3_02 = stats::filter(price, rep(1,n) / n, sides = 2) # 前後の数値を参照
   ) 
datepricemove_3move_3_02
2018/2/18854260
2018/2/24636510
2018/2/31611720012276316
2018/2/41956190013369104
2018/2/5122117101227631615838202
2018/2/6143182001336910416519518
2018/2/7169820001583820216894638
2018/2/8195237801651951816127068
2018/2/9214375001689463815354068
2018/2/1083738601612706815375798

移動平均を使ったグラフ1

次に移動平均の期間をわけたグラフの作成です。株価の分析でよく使うように変更することもできます。

n_1 <- 3
 n_2 <- 5
 n_3 <- 7
 d %>% 
   group_by(date) %>% 
   summarise(price = sum(price,na.rm = T)) %>% 
   mutate(
     move_ave = stats::filter(price, rep(1,n_1) / n_1, sides = 1), # 過去数値を参照
     move_ave_2 = stats::filter(price, rep(1,n_2) / n_2, sides = 1), # 前後の数値を参照
     move_ave_3 = stats::filter(price, rep(1,n_3) / n_3, sides = 1) # 前後の数値を参照
   ) %>% 
   gather(key = "name",value = "value",-date) %>% 
   ggplot(aes(x = date,
              y = value,
              group = name,
              col = name)) +
   geom_line() +
   geom_point()

移動平均を使ったグラフ2

次は見せ方に工夫を加えたグラフの作成です。また、デフォルト表示順番だと、分析しづらいのでを表示順序の調整もしています。

# データ作成
 d_2 <-    d %>% 
   group_by(date) %>% 
   summarise(price = sum(price,na.rm = T)) %>% 
   mutate(
     move_ave = stats::filter(price, rep(1,n_1) / n_1, sides = 1), # 過去数値を参照
     move_ave_2 = stats::filter(price, rep(1,n_2) / n_2, sides = 1), # 前後の数値を参照
     move_ave_3 = stats::filter(price, rep(1,n_3) / n_3, sides = 1) # 前後の数値を参照
   ) %>% 
   gather(key = "name",value = "value",-date) 

# 表示順序の修正
 d_2$name <- as.factor(d_2$name)
 levels(d_2$name)  <- c("price","move_ave","move_ave_2","move_ave_3")

# グラフ作成
 d_2 %>% 
 ggplot(aes(x = date,
            y = value,
            group = name,
            col = name)) +
   geom_line() +
   geom_point() +
   facet_grid(name ~ .)