日時データの操作
Text Update: 11/10, 2018 (JST)

日時は数値扱いでであったり文字列扱いであったり、さらに書式が一定しておらず分析処理する場合には厄介なデータです。このような日時データを扱う場合は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月)
  • 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