日時は数値扱いでであったり文字列扱いであったり、さらに書式が一定しておらず分析処理する場合には厄介なデータです。このような日時データを扱う場合はtidyverse
パッケージファミリーであるlubridate
パッケージを利用するのがおすゝめです。
Packages and Datasets
本ページではR version 3.4.4 (2018-03-15)の標準パッケージ以外に以下の追加パッケージを用いています。
Package | Version | Description |
---|---|---|
tidyverse | 1.2.1 | Easily Install and Load the ‘Tidyverse’ |
lubridate | 1.7.4 | Make Dealing with Dates a Little Easier |
Rにおける日時情報
R では日付(オブジェクト)を扱うためのDate
クラスと年月日時分秒(オブジェクト)を扱うためのPOSIX
クラスがあります。POSIX
クラスには以下のクラスがあります。
クラス | 概要 | 備考 |
---|---|---|
POSIXct1 | 1970年1月1日からの経過秒を用いて年月日時分秒を表す | ANSI C “Calender Time” |
POSIXlt | 名前ラベルを持つ文字列リスト(可読性が高い) | ANSI C “Local Time” |
POSIXt | POSIXctとPOSIXltの両者を含む | Rでは扱いなし |
1 POSIXct
クラスは、UNIXタイム(UNIX時間、UNIX時刻)と呼ばれるものと同じ時刻表現です。
基本的な処理
yyyy-mm-dd
形式の日付をPOSIXct
形式に変換するために下記の関数が用意されています。
関数 | 概要 | 備考 |
---|---|---|
lubridate::as_date |
タイムゾーンの日付を返します | |
as.Date |
UTC(協定世界時)での日付を返します |
フォーマット変換
日付はロケールにより様々な書式(フォーマット)で扱われています。yyyy-mm-dd
形式でない日付をyyyy-mm-dd
形式に変換するには下記の補助関数を用います。
関数 | 概要 | 備考 |
---|---|---|
lubridate::dmy |
dd-mm-yyyy形式用 | セパレータは/ も可 |
lubridate::dym |
dd-yyyy-mm形式用 | 同上 |
lubridate::mdy |
mm-dd-yyyy形式用 | 同上 |
lubridate::myd |
mm-yyyy-dd形式用 | 同上 |
lubridate::ydm |
yyyy-dd-mm形式用 | 同上 |
lubridate::ymd |
yyyy-mm-dd形式用 | 同上 |
as.Date |
オプションで上記関数と同様の処理が可 | セパレータはオプション指定 |
なお、日本語形式(例:2017年12月26日)の場合でも変換可能です。また、日付に時刻が含まれる場合でも上記の補助関数に以下のサフィックスがついた補助関数を使うことで同様の処理が可能です。
関数 | 概要 | 備考 |
---|---|---|
_h |
時までを返します | |
_hm |
時分までを返します | |
_hms |
時分秒までを返します |
タイムゾーン
タイムゾーンを指定する場合は、各関数、各補助関数に対してtz
オプションを指定します。tz
オプションで使えるタイムゾーンはOlsonNames()
で一覧を取得できます。
特定の情報を抽出する
日時情報から特定の情報を抽出することも可能です。
情報 | 関数 | 備考 |
---|---|---|
年 | year , isoyear , epiyear |
年、ISO 8601、epidemiological |
四半期 | quarter |
返り値は数値型 |
月 | month |
表示はロケールに依存 |
週 | week , isoweek , epiweek |
元旦からの週番号、ISO 8601、epidemiological |
曜日 | wday |
表示はロケールに依存 |
日 | day , mday , yday |
日、月初からの日番号、年初からの日番号 |
時 | hour |
|
分 | minute |
|
秒 | second |
週(週番号)
年初から第何週目なのか、いわゆる週番号を求めるには、いくつかの方法がありますので目的に応じて選択してください。
関数 | 処理概要 | 備考 |
---|---|---|
lubridate::epiweek |
epidemiological week(EPI weeks, CDC weeks) | 日曜開始 |
lubridate::isoweek |
ISO 8601 の週番号(ISO weeks) | 月曜開始 |
lubridate::week |
1月1日を基準に7日単位で週番号を計算する |
週(月内の週数)
月初から第何週目(以降、月内週数と呼称)なのかを求める関数はありませんので、月内週数を求めたい日の週番号から月初日(当月の1日)の週番号を差し引いて求める必要があります。しかし、週番号は前述のように様々な定義がありますので計算方法には注意してください。
特にカレンダーをイメージした月内週数を得たい場合にはlubridate::isoweek
関数またはlubridate::epiweek
関数を使用する必要があります。
lubridate::isoweek
の場合、週の始まりは月曜日- 1月の最初の週は前年の最終週(第52または53週)になる場合がある(例:2016年1月)
- その年の最初の木曜日を含む週がその年の第1週という定義のため
- 12月の最終週は翌年の第1週になる場合がある(例:2014年12月)
- 1月の最初の週は前年の最終週(第52または53週)になる場合がある(例:2016年1月)
lubridate::epiweek
の場合、週の始まりは日曜日- 週の開始以外はISO weekに準拠
上記の条件を考慮して月内週数は以下の計算で求めます。
\[月内週数を求めたい日の週番号 - 月初日の週番号 + offset\]
月初日(1日)はlubridate::floor_date
関数で求めることができますので上記の式は以下のコードとなります。
ISO weeksの場合
lubridate::isoweek(x) - lubridate::isoweek(lubridate::floor_date(x), "month") + offset
EPIdemiological weeksの場合
lubridate::epiweek(x) - lubridate::epiweek(lubridate::floor_date(x), "month") + offset
offset
は条件により値が異なる点に注意してください。
条件 | offsetの値 | 備考 |
---|---|---|
月初日の週番号が第52週の場合 | 53 | 1月のみ |
月初日の週番号が第53週の場合 | 54 | 1月のみ |
月初日週番号 > 求めたい日の週番号 | 53 | 12月の最終週が第1週の場合 |
上記以外 | 1 |