DS講座 tidyverse tidyverse講座

【R前処理講座32】{lubridate}:時間処理【tidyverse】

こんにちは,shun(@datasciencemore)です!

ついに..ついに今回の時間処理でこのR前処理講座が終了します!!!
長かった...

時間処理は最後を飾るにふさわしい,まさにラスボスといってもいいでしょう.
少しめんどくさいところもありますが,めげずに食らいついていきましょう!

0.{lubridate}ってなに??

{lubridate}ってなんですか??
{lubridate}は,時間処理に特化したパッケージのことだよ.

時間処理は簡単そうに見えるけど,実際に処理しようとすると色々考えることが多くて難しいんだ...

時間処理は,一見単純のようにみえるのですが,実は奥が深く,とても考えることが多いです.
ややこしい例を挙げると

  1. 通常は1年は365日だが,うるう年は1年は366日
  2. 通常は1日は24時間だが,サマータイム時は25時間
  3. 時差の影響により,国々の時刻は異なる.

などなど,めんどくさいことがたくさんでてきます.

時間処理を完全に理解することは難しいですが,この記事ではデータ分析でよく使用する時間処理についてに焦点を当てて説明したいと思います.

さて,baseRでは,時刻を表す型として,POSIXc型,POSIXlt型がありますが,これらの使い方は覚えなくて大丈夫です笑

これらの使い方は難しすぎるので僕は挫折しました...笑
後述のlubridateですべて代用できるので安心してください!

これらの代わりに時間処理を扱うパッケージ,{lubridate}について紹介します.
これを使いこなせれば,時間処理については問題ないです!

lubridateを使用すると,時間型を以下の2種類に分類できます.

  1. date型:日付を表す.
  2. datetime型:日付と時刻を表す.

実は,time型というのもあるのですがほとんど使用せず,上で挙げた2つの型で代用できるので割愛いたします.
ちなみにtime型,僕も実務で使ったことは1度もありません.

それでは,lubridateの代表的な使い方を紹介していきます.

 

1.文字列から時間型を作成

date型,datetime型を作成するには,y, m, d, h, m, sの6文字を文字列の要素に対応するように指定すればlubridateがいい感じに変えてくれます.
例えば,"2020/12/17"という文字列をdate型にする場合,ymd("2020/12/17")とするだけです.
同じ色の対応を見比べてみてください.
lubridate様,さすがっす.

y, m, d, h, m, sの6文字は,それぞれ次の意味です.
y:year(年)
m:month(月)
d:day(日)
h:hour(時)
m:minute(分)
s:second(秒)

それでは,具体的なコードをいろいろ見ていきましょう.

 

 

lubridateを使うと,「-」とか「/」を自動的に判断して,date型もdatetime型もいい感じに変換してくれます.

 

2.要素から時間型を作成

要素(年,月,日など単一の値)から時間型を作成することもできます. date型ならmake_date,datetime型ならmake_datetimeを使用します.

 

 

これは,データフレームに列に年や月の情報が個別にあるとき,そこから時間型を作成するときに便利です.
例えば以下のようなデータフレームがあるとして,そこからdatetime型をmake_datetimeを使用して作成してみましょう.

 

 

 

3.時間型の変換

as_dateを使用するとdatetime型からdate型へ,as_datetimeを使用するとdate型からdatetime型へ変換できます.

 

4.要素の取得

日付時刻の各要素を取得する便利関数がいくつかあります.
その関数を以下のように時間型に適用すると,時間型の一部分を抽出できます.

全部だと多いので一例を紹介しますね.

 

  また,ydayとwdayという関数は,それぞれ年初から何日目か,今週何日目かを教えてくれます.

 

monthとwdayは,label = TRUEと設定すると,該当する月,曜日のfactorが取得できます.

いやー,親切すぎるぜlubridate...
ここまで親切だともうbaseRに戻れませんね笑

 

5.時間型の丸め処理

以下の3種類の関数で,時間型を丸めることができます.

  • floor_date:切り捨て
  • round_date:四捨五入
  • ceiling_date:切り上げ

 

 

 

6.時間型の計算

ここでは,時間型の計算についてやっていきます.
例えば,自分が生まれてからどれくらい時間がたったのかを知りたいとしましょう.
そのようなときに,(現時点 - 生年月日)で引き算すればできそうですね.
このように時間型を使用して,いろいろな計算ができると便利ですね.
この時間型の計算をするうえで大事になってくるのが以下の3つのクラスです.

  1. duration
  2. period
  3. interval

それぞれについてじっくり見ていきましょう.

6.1 duration

以下の関数で指定した数値durationが取得できます.
durationは,秒で表しています.

  • dseconds
  • dminutes
  • dhours
  • ddays
  • dweeks
  • dyears

一例をあげますね.

 

6.2 period

以下の関数で指定したperiodが取得できます.

  • seconds
  • minutes
  • hours
  • days
  • weeks
  • years

こちらも一例を示します.

 

うーん,durationとperiodの違いがよくわからないです...
そうだよね,ここはとてもややこしいところなんだ.

durationは常に秒で表されるのに対して,periodは人間の時間間隔を表しているんだ.

例えば,2016年1月1日の1年後っていったら私たち人間の感覚だと2017年1月1日だよね?

ところが,2016年1月1日の31557600秒(1年を秒に換算した値)後は,2016年の12月31日になるんだ.

これは,2016年はうるう年で,年間366日あるから結果が異なるんだね.

いやー,わかりづらい笑
イメージにすると少しはわかりやすくなるでしょうか?

periodを使用するときは,起点となる時刻によって,同じ関数を使用しても値が異なってくるんですね.
この図の上の例の場合,2016年はうるう年なので1年=366日です.
2016年1月1日にyears(1)を足すと,2016年1月1日の1年後と人間の感覚で解釈されるため,years(1) = 366日となるんですね.
一方,durationであるdyears(1)は,起点が何であろうが関係ありません.常に31557600秒後です.
この違いによって,最終的な結果が1日異なるのです.
この図の下の例も参考にみてみてください.
2017年は普通の年なので,1年=365日です.
よって,years(1)もdyears(1)も同じ365日を表すのです.

またまたややこしくことで大変恐縮なのですが,実は正確にいうと365日は,3600秒×24時間×365日 = 31536000秒なので,dyears(1)と微妙に違います.
これは天文学で1年 = 365.25日と定義しているため,dyears(1)も365.25日の秒数 = 31557600秒としているみたいです.(Wikipedia情報)
なので,上の例は完璧に正確ではないですが,イメージを理解するうえで有用なので,載せてあります.
ややこしすぎやろ...笑
lubridateのバージョンによっても変わってきそうなので,そこまで神経質にならないで,なんとなくのイメージをつかめていただければOKです.

Rで確認してみましょう.

 

 

こんな感じです.
durationを足したら時刻が出てきちゃった理由は,上述の注意書きのとおりです.
あんまり深く考えないようにしましょう笑

 

6.3 interval

intervalは,開始時点と終了時点を指定し,その期間をdurationで表したものになります
durationなので,単位は秒ですね. 普通のdurationとの違いは,intervalは開始時点の情報があるということです.
intervalで使用する主な関数は以下のとおりです.

  • %within% : intervalに含まれているか.
  • int_start : intervalの開始時点
  • int_end: intervalの終了時点
  • int_overlap : 2つのintervalが重なっているか.
  • int_length : intervalの秒数
  • int_shift : intervalを指定分,ずらす.

intervalを以下のように定義します.

この例をもとにRで確認していきましょう.

上の図とコードを見比べて,何をしているのか確認してみてくださいね.

 

まとめ

今回は時間処理について以下のことをやりました.

  1. 文字列から時間型を作成
  2. 要素から時間型を作成
  3. 時間型の変換
  4. 要素の取得
  5. 時間型の丸め処理
  6. 時間型の計算

いやー,お疲れさまでした!
かなり難しかったと思います.
これを使いこなせれば,時間処理についてはほぼ完ぺきです.
最初は難しいと思いますが,1つずつ理解していきましょう.

これでR前処理講座は今度こそ終了です!!
皆様お疲れさまでした!!!
これがすべて理解できたら前処理マスターを名乗っていいと思います.
R前処理講座は,前処理の8割程度をカバーしていると考えています.
残りの2割は適宜ググって解決していきましょう.
別に前処理に限りませんが,完璧を目指すことはよくないですよ!!

それじゃ,お疲れさまでした!!!

参考

  1. https://www.amazon.co.jp/R%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9-Hadley-Wickham/dp/487311814X
  2. https://www.medi-08-data-06.work/entry/how_to_use_lubridate1902
  3. https://ja.wikipedia.org/wiki/%E5%B9%B4#:~:text=%E5%A4%A9%E6%96%87%E5%AD%A6%E3%81%A7%E3%81%AF%E8%A8%88%E9%87%8F%E3%81%AE%E5%8D%98%E4%BD%8D,%E3%81%A8%E5%AE%9A%E7%BE%A9%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82

-DS講座, tidyverse, tidyverse講座