定期的なイベントを年月日でいい感じに扱うパッケージ almanac
この記事は何?
本記事はRのパッケージ almanac パッケージの紹介です。こちらのGithubに記載してある内容を試した記事になります。 ※一部間違っており修正しました。
モチベーション
10月の第2月曜日は何の日でしょう。そう、スポーツの日です。
では、過去10年間のスポーツの日の日付はいつでしたか。と聞かれると一手間かかりますが、そんな一手間を解消してくれそうなパッケージを見つけたので試してみつつ紹介記事を書きます。
インストール
remotes
パッケージをあらかじめインストールしてください。
vctrs
もgithubにある物をインストールしてください。
remotes::install_github("DavisVaughan/almanac")
Mac,Windowsユーザーは問題ないですが、Linuxユーザーの方は上記のページを参照ください。
例:定期的な予定を扱う
例として、thanksgivingが挙げられています。ここでは、11月の第4金曜日というルールのオブジェクトを作っています。
# Thanksgiving = "The fourth Thursday in November" on_thanksgiving <- yearly() %>% recur_on_ymonth("November") %>% recur_on_wday("Thursday", nth = 4) on_thanksgiving > <rrule[yearly / 1970-01-01 / 2040-01-01]> > - ymonth: Nov > - wday: Thu[4]
ルールオブジェクトを生成できたら、これから実際に日付を生成できます。
alma_search("2000-01-01", "2006-12-31", on_thanksgiving) [1] "2000-11-23" "2001-11-22" "2002-11-28" "2003-11-27" "2004-11-25" "2005-11-24" "2006-11-23"
また、日付に対してルールに該当するかの判定もすることができます。
# Is this a Thanksgiving? alma_in(c("2000-01-01", "2000-11-23"), on_thanksgiving) #> [1] FALSE TRUE
ルールに該当する日を飛ばした日付計算をすることもできます。 2000年は11月23日がthanksgivingでしたが、 11月22日と23日で23日を飛ばした場合の2日後は同じになるという雰囲気です。
step_over_thanksgiving <- stepper(on_thanksgiving) base_date <- as.Date("2000-11-22") base_date %s+% step_over_thanksgiving(2) "2000-11-25" base_date <- as.Date("2000-11-23") base_date %s+% step_over_thanksgiving(2) "2000-11-25"
発展
複数のルールをまとめて扱うこともできる。その場合は、個別のルールーをバンドルしたオブジェクトを作って扱う必要がある。
# 毎週末のルール on_weekends <- weekly() %>% recur_on_weekends() # クリスマスのルール on_christmas <- yearly() %>% recur_on_mday(25) %>% recur_on_ymonth("Dec") # thanksgivingと週末とクリスマスのルールをまとめたルールを作る bundle <- rbundle() %>% add_rschedule(on_weekends) %>% add_rschedule(on_christmas) %>% add_rschedule(on_thanksgiving)
日本の出勤日のルールを作ってみる
手を抜いて祝日を除く出勤日ではない日をまとめると、
- 週末
- 年末年始(12/28-1/3)
#----------------------------- on_yearends <- rbundle() %>% add_rschedule( yearly() %>% recur_on_ymonth("Dec") %>% recur_on_mday(28) ) %>% add_rschedule( yearly() %>% recur_on_ymonth("Dec") %>% recur_on_mday(29) ) %>% add_rschedule( yearly() %>% recur_on_ymonth("Dec") %>% recur_on_mday(30) ) %>% add_rschedule( yearly() %>% recur_on_ymonth("Dec") %>% recur_on_mday(31) ) #----------------------------- on_yearstarts <- rbundle() %>% add_rschedule( yearly() %>% recur_on_ymonth("Jan") %>% recur_on_mday(1) ) %>% add_rschedule( yearly() %>% recur_on_ymonth("Jan") %>% recur_on_mday(2) ) %>% add_rschedule( yearly() %>% recur_on_ymonth("Jan") %>% recur_on_mday(3) ) #--------------------------- on_japanese_weekday <- rbundle() %>% add_rschedule(on_yearends) %>% add_rschedule(on_yearstarts) library(stringr) date_list <- seq(as.Date('2020-01-01'), as.Date('2020-12-31'), 1) !alma_in(date_list, on_japanese_weekday)
※上記のコードが"Feb"になっていたのを"Jan"に修正しました。
[1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [18] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [35] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [52] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [69] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [86] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [103] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [120] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [137] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [154] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [171] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [188] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [205] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [222] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [239] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [256] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [273] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [290] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [307] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [324] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [341] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [358] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
結構便利かも。
以上、さくっと紹介でした。