メモ:lubridateパッケージで区間を指定したいときはperiod、ざっくり時刻計算したいときはduration
任意の時刻型について、floor_date()
で区切った区間のちょうど真ん中を返す関数を作りたい。こんな感じの。
library(lubridate) mannaka <- function(x, binwidth_hour) { floor_date(x, hours(binwidth_hour)) + hours(binwidth_hour)/2 }
floor_date()
とかの区間は"minutes"
みたいな文字列だけではなくperiod
でも指定できるの知ってました? けっこう便利です。
で、これは一見うまく動きます。
mannaka(Sys.time(), 2) #> [1] "2018-02-25 15:00:00 JST"
しかし、区間の長さを1にするとうまくいかない。
mannaka(Sys.time(), 1) #> Error in validObject(.Object): invalid class "Period" object: periods must have integer values
これは、Period
は日付上意味のある切れ目を表すもので、常に一定の長さを持っているとは限らないからです。
つまり具体的には、1時間が3600秒とは限らないわけです。うるう秒とかあるし。
しかしここで足し算をしてるのはそんな厳密な話ではなくて、区間のだいたい真ん中を指してくれればいい。
ということで、そんなときはduration
です。これはPeriod
をつくる関数の頭にd
をつけた関数名になっています。
dhours(1)/2 #> [1] "1800s (~30 minutes)"
ということで、さっきのdhours()
をhours()
に変えてやってみますがうまくいきません。
mannaka2 <- function(x, binwidth_hour) { floor_date(x, dhours(binwidth_hour)) + dhours(binwidth_hour)/2 } mannaka2(Sys.time(), 1) #> Error: Invalid period name: s
floor_date()
は厳密な区間の区切りを求めるので、ここで使うのはPeriod
でなければいけません。ということで前者はhours()
に戻すのが正解。
mannaka3 <- function(x, binwidth_hour) { floor_date(x, hours(binwidth_hour)) + dhours(binwidth_hour)/2 } mannaka3(Sys.time(), 1) #> [1] "2018-02-25 15:30:00 JST"
むずい...