いずにゃんの研究日記

専門性を広げるための練習場

はじめてのlubridate(1)日付データを扱う

追記:30万本目達成のデータ追加(2017/11/03)

日付データは,Rの基本的な関数だと初学者では扱うのがけっこう大変である。それを簡単にしてくれる,まじでラブリーなパッケージがlubridateだ。

単純なデータで練習するために,今や全国で大人気となったのっぽパンの,ラブライブ!サンシャイン!!とのコラボ商品「塩キャラメルのっぽ」味の累計売上本数を日付と共にグラフにし,それぞれどれだけの日数を要したか確認するまでを解説する。

沼津駅の改札を出てすぐの所にある売店でもこの通りの充実ぶり

f:id:izunyan:20170507000211j:plain

データの情報源は以下の通り。

静岡のご当地パン「のっぽパン」と「ラブライブ!サンシャイン!!」のコラボが決定! | 株式会社バンデロール

のっぽ×ラブライブ!サンシャイン!! コラボパンの累計販売数が10万本突破! | 株式会社バンデロール

twitter.com

twitter.com


データを読み込む

library(tidyverse)
library(lubridate)

データの読み込みは,今後の情報追加時の更新作業が分かりやすい配置になるように,tribble()で実施してみる。

dat <- tribble(
  ~date,           ~hon,
  "2016/09/13",        0,
  "2016/11/09",   100000,
  "2017/04/15",   200000,
  "2017/10/30",   300000
)
dat

日付は文字型にしておく必要があるため," "で囲っている。データフレームを表示すると以下のような感じになる

# A tibble: 4 x 2
        date   hon
       <chr> <dbl>
1 2016/09/13 0e+00
2 2016/11/09 1e+05
3 2017/04/15 2e+05
4 2017/10/30 3e+05


日付変数に変換する

ここでlubridateの出番である。日付の情報が,year-month-dayの順番で並んでいるので,それぞれの頭文字をとった関数ymd()を使うだけでお手軽に変換できる。

dat <- dat %>%
  mutate(date2 = ymd(date)
           )
# A tibble: 4 x 3
        date   hon      date2
       <chr> <dbl>     <date>
1 2016/09/13 0e+00 2016-09-13
2 2016/11/09 1e+05 2016-11-09
3 2017/04/15 2e+05 2017-04-15
4 2017/10/30 3e+05 2017-10-30

このように,変数の型も<date>になった。

なお,ここの作業に関連する関数は他にもydm(),mdy(),myd(),dmy(),dym()があり,年月日がどんな順番でも対応可能なことが分かる。たとえば,

dmy("13/09/2016")
[1] "2016-09-13"

他にも,year-month-day hour-minute-secondに対応した,ymd_hms()などもあるが,今回は扱わない。

年月日の区切りは様々なタイプに対応しており,区切りなしや区切りが空白といった場合でも同様に読み込める。たとえば,

dmy("09 Nov 2016")
[1] "2016-11-09"

詳しくは,ymd()などのhelpのexample参照。


横軸が日付で縦軸が売上本数の線グラフを描いて,それぞれの達成日を点で示す

p <- dat %>% 
  ggplot(aes(x = date2, y = hon)) +
  geom_line()+
  geom_point()
p

f:id:izunyan:20171103104113j:plain

横軸の日付表示がざっくりすぎるのと,時点数の表示が少ないので,横軸を1カ月ごとの表示にしてみる

p + scale_x_date(date_breaks="1 month")

f:id:izunyan:20171103104126j:plain

日付の文字が長く重なってしまうので,角度を45度にしてみる

p +
  scale_x_date(date_breaks="1 month") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

f:id:izunyan:20171103104152j:plain

縦軸の本数の表示が分かりにくいので,コンマをつけてすべて表示させる

p +
  scale_x_date(date_breaks="1 month") +
  scale_y_continuous(labels = scales::comma) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

f:id:izunyan:20171103104158j:plain

さて,グラフを見ると最初の10万本達成までの伸びが急激で,その後20万本までは少し緩やかになり,30万本目までもほぼ同じ勢いで伸びている。次は,時点間の日数が何日だったかについて確認してみる


時点間の日数を計算して変数にする

これは,date2の値について,前の行の値との差を計算すればよい。dplyrlag()関数が便利である。引数のdefault = date2[1]というのは,前の行がない1行目の結果をどうするかの指定で,デフォルトではNAを返すが,ここでは同じ1行目を指定しているので,0が返ってくる。

dat <- dat %>%
  mutate(date_dif = date2 - lag(date2, default = date2[1]))
dat
# A tibble: 4 x 4
        date   hon      date2 date.dif
       <chr> <dbl>     <date>   <time>
1 2016/09/13 0e+00 2016-09-13   0 days
2 2016/11/09 1e+05 2016-11-09  57 days
3 2017/04/15 2e+05 2017-04-15 157 days
4 2017/10/30 3e+05 2017-10-30 198 days

最初の2か月だけでみると

> 100000/57
[1] 1754.386

なので,1日あたり1754本売れていたことになる。