ねこすたっと

ねこの気持ちと統計について悩む筆者の備忘録的ページ。

日付・時間の操作(1):時間型データを作成する・要素を抽出する(lubridateパッケージ)[R]

lubridateパッケージ*1を使うと日付・時刻型データ(単純に時間型データと呼ぶことにします)の扱いがとても楽になる。 lubridateパッケージはtidyverseのコアパッケージには含まれていないので、別に読み込みする必要あり。

library(tidyverse)
library(lubridate)

時間型データの種類

時間型データとして次の3種類を扱う。

  • date型:日付のみ(例:1985年10月26日)
  • datetime型:日付と時刻(例:1985年10月26日1時24分0秒)
  • time型:時刻のみ(例:1時24分0秒)

自分が使うのはほとんどdate型。

ymd_hms( )を使って文字列から時間型データを作成する

年月日の表記方法は国はもちろん、人や案件によってもバラバラなので、ちょっと面倒なときがある。 ここで説明するymd( )系の関数に日付・時刻っぽい文字列を入力すると、時間型データとして認識できるようにしてくれる。 関数名は認識させる要素(=年・月・日・時・分・秒)の順序を示しているので、例えば、日・月・年の順序で書かれていることを認識させたければdmy( )とする。

  • y:year(年)
  • m:month(月)
  • d:day(日)
  • h:hour(時)
  • m:minute(分)
  • s:second(秒)

関数名で認識する順番を指定していれば、区切り記号は大体なんでもよさそう。 下の例のように、色々な書き方で入力してみる。

ymd("19851026")
ymd("1985年10月26日")
mdy("Oct/26/1985")
dmy("26th,October,1985")
[1] "1985-10-26"

どれも正しく認識された。

下のように、ベクトルを引数にすることもできる。その際は、違うフォーマットが混ざっていてもOK。

ymd(c("1955/11/12", "1985.10.26"))
[1] "1955-11-12" "1985-10-26"

ymd( )で文字列date型として認識する要領で、ymd_hms( )やhms( )を使ってdatetime型あるいはtime型として認識できる。

> ymd_hms("19851026012400")
[1] "1985-10-26 01:24:00 UTC"
> ymd_hms("19851026012400")
[1] "1985-10-26 01:24:00 UTC"
> ymd_hm("1985/10/26/1/24")
[1] "1985-10-26 01:24:00 UTC"
> hms("1/24/00")
[1] "1H 24M 0S"

hms( )では数字の羅列だとエラーが出るときがある。124と並んでいても1時なのか12時なのか分からないからだろう。だから記号で区切る方が無難。あと、hms( )では順序を入れ替えたもの(例:shm( ))はないみたい。

時間帯(タイムゾーン)

時刻を認識させると最後に"UTC"とついてくるが、これは協定世界時(Coordinated Universal Time)のこと。グリニッジ標準時(Greenwich Mean Time, GMT)とはほんの少しだけ違う。

日本標準時(Japan Standard Time, JST)として認識したければ、tz = "Asia/Tokyo"あるいはtz = "Japan"と付け加える。

ymd_hms("1985-10-26 1:24:00", tz="Asia/Tokyo")
ymd_hms("1985-10-26 1:24:00", tz="Japan")
[1] "1985-10-26 01:24:00 JST"

指定できるタイムゾーンのリストはOlsonNames()で表示可能(これ以外にも受け付けてくれるみたいだが、日本ではタイムゾーンを意識することがあんまりないので割愛)。

make_datetime( )を使って数値から時間型データを作成する

文字列から時間型データを作る以外にも、make_date( )やmake_datetime( )の引数(year, month, day, hour, min, sec)に数値を指定することで時間型データを作成することができる。引数tzでタイムゾーンも指定できる。入力していいない引数に対してはデフォルトの値(year=1970L, tz="UTC")が当てられる。

> make_datetime(1985,10,26,1,26,0)
[1] "1985-10-26 01:26:00 UTC"

次のように、年・月・日を別の列に収納したデータシートを扱うときに使いそう。

time_df = 
  tibble(
    year = 2020,
    month = 12,
    day = 1:31,
  ) %>% 
  mutate(
    datetime = make_date(year, month, day)
  )
> time_df
# A tibble: 31 × 4
    year month   day datetime  
   <dbl> <dbl> <int> <date>    
 1  2020    12     1 2020-12-01
 2  2020    12     2 2020-12-02
 3  2020    12     3 2020-12-03
 4  2020    12     4 2020-12-04
 5  2020    12     5 2020-12-05
 6  2020    12     6 2020-12-06
 7  2020    12     7 2020-12-07
 8  2020    12     8 2020-12-08
 9  2020    12     9 2020-12-09
10  2020    12    10 2020-12-10
# … with 21 more rows

時間型データの各要素を抽出する

例として使う日付・時刻をdatetime0として保存しておく。

datetime0 <- ymd_hms("1985-10-26 1:24:00") 

日付を取り出す場合はdate( )を使う。

> date(datetime0)
[1] "1985-10-26"

as_date( )でもよい。

> as_date(datetime0)
[1] "1985-10-26"

その他に抽出できる要素と関数は以下のとおり。

  • date( ):年月日(説明済み)
  • year( ):年
  • month( ):月(後述)
  • week( ):その年の第何週目か
  • day( ):日
  • wday( ):その週の第何日目か(後述)。
  • mday( ):その月の第何日目か(使いときある??)
  • yday( ):その年の第何日目か
  • minute( ):分
  • second( ):秒
  • tz( ):時間帯
  • quarter( ):第何四半期か(後述)
  • semester( ):上半期・下半期(後述)

日付を曜日に変換する

wday( )で「その週の第何日目か(日曜=1)」が返ってくるので、これを使えば曜日に変換できる。

そのままだと次のように数字が返ってくる。わかりにくい。

> wday(datetime0)
[1] 7

そこで引数label=TRUEとすると曜日の名前で返してくれる。略称にしたくなければ引数abbr=FALSEを指定。

wday(datetime0, label = TRUE, abbr = TRUE)
[1] Sat
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

ちなみにmonth( )で月を抽出するときも、同じ引数を指定できる。

month(datetime0, label = TRUE, abbr = FALSE)
[1] October
12 Levels: January < February < March < April < May < June < ... < December

半期・四半期に変換する

semester( )は、上半期(1月〜6月)か下半期(7月〜12月)を数字で返す。

> semester(ymd("2020-06-30"))
[1] 1

引数with_yearにTRUEを指定すると、「年」と一緒に抽出される(半期毎の数値をグラフにするときは便利)。

> semester(ymd("2020-07-1"), with_year = TRUE)
[1] 2020.2

quarter( )は第何四半期にあたるかを数字で返す。

  • Q1:1月〜3月
  • Q2:4月〜6月
  • Q3:7月〜9月
  • Q4:10月〜12月
> quarter(datetime0)
[1] 4

quarter( )もsemester( )と同様、引数with_yearを指定できる。

時間型データが条件に該当するか判定する

与えられた日付・時刻が条件に当てはまっているか、その真偽を返す。

  • am( ):午前中(0:00:00〜11:59:59)
  • pm( ):午後中(12:00:00〜23:59:59)
  • leap_year( ):うるう年
  • dst( ):daylight saving time*2

使い方は下のとおり。至ってシンプル。

> leap_year(ymd("2000-01-01"))
[1] TRUE

おわりに

  • 記事ストックがほとんどない状態でシーズン5に突入してしまいました。
  • 後編も書いてます。

necostat.hatenablog.jp

参考資料

  • UTC, GMT, JSTについて参考にさせていただきました。

www.quicktranslate.com

  • Rを使った解析前のデータ処理について系統立てて解説してくださっています。

datasciencemore.com

  • こちらもわかりやすく解説してくださっています。

www.medi-08-data-06.work

*1:lubricate(円滑にする)より?

*2:https://ja.wikipedia.org/wiki/%E5%A4%8F%E6%99%82%E9%96%93