R言語における日本の祝日判定
Rにおいて日本の祝日を判定する方法を解説します。
『内閣府:「国民の祝日」について』で提供されている祝日のデータを用いて祝日判定を行います。
いままでNipponパッケージを使って祝日判定をする方法を紹介してきました。しかしNipponパッケージが2019年7月現在、使用できなくなっています。
祝日判定をするだけでしたら、比較的短いコードで実装が可能です。この記事ではパッケージを使わずに祝日判定を行います。
なお拙著『時系列分析と状態空間モデルの基礎:RとStanで学ぶ理論と実装』においてもNipponパッケージを用いています。
こちらの書籍をお持ちの方は、Nipponパッケージを使う代わりに、この記事で紹介されている方法を用いてください。
『内閣府:「国民の祝日」について』で提供されているデータを使用しています。こちらのページのURLが変更されてコードが動かなくなった等の問題があれば、コメントなどでお知らせいただけますと幸いです。
コードはすべてGitHubで公開しています。
当方で簡単な動作確認を行いましたが、結果を保証するものではありません。参考程度にお使いください。
何か問題があれば、コメントなどでお知らせいただけますと幸いです。
目次
1.祝日判定をする関数の基本的な使い方
ネットに接続されていることを前提として、祝日判定をする関数の基本的な使い方を見ていきます。
関数の名前はis.jholidayです。これはNipponパッケージの関数名に合わせています。
基本的な使い方
(2020年10月2日追記)
下記の『祝日判定関数:is.jholiday』において、文字コードが指定できるように修正しました。
ただしデフォルト引数として「 “CP932″」を与えているので、単に「is.jholiday(target_date = target_date)」とするだけで動作する点は今までと同じです。
(追記終わり)
関数はWeb上で公開されているので、以下のコードを実行するだけで、いつでも『祝日判定関数:is.jholiday』が使えるようになります。
# 関数の読み込み
source("https://raw.githubusercontent.com/logics-of-blue/website/master/010_forecast/20190714_R%E8%A8%80%E8%AA%9E%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E6%97%A5%E6%9C%AC%E3%81%AE%E7%A5%9D%E6%97%A5%E5%88%A4%E5%AE%9A/jholiday.R", encoding="utf-8")
仮に、2019年5月1日から5月31日までの祝日を判定したいと思ったとします。
判定対象となる日付を用意します。
# 祝日判定をしたい日付データ
target_date <- seq(
from = as.Date("2019-05-01"),
to = as.Date("2019-5-31"),
by = 1
)
結果はこちら
> target_date [1] "2019-05-01" "2019-05-02" "2019-05-03" "2019-05-04" [5] "2019-05-05" "2019-05-06" "2019-05-07" "2019-05-08" [9] "2019-05-09" "2019-05-10" "2019-05-11" "2019-05-12" [13] "2019-05-13" "2019-05-14" "2019-05-15" "2019-05-16" [17] "2019-05-17" "2019-05-18" "2019-05-19" "2019-05-20" [21] "2019-05-21" "2019-05-22" "2019-05-23" "2019-05-24" [25] "2019-05-25" "2019-05-26" "2019-05-27" "2019-05-28" [29] "2019-05-29" "2019-05-30" "2019-05-31"
is.jholiday関数を使えば、祝日ならTRUE、そうでなければFALSEを返してくれます。
2019年のゴールデンウイークにおける、振替休日を含めた祝日の判定ができました。5月1日から6日までが祝日となっています。
> # 日付において、祝日ならTRUE、そうでなければFALSEを返す > is.jholiday(target_date = target_date) [1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE [11] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [21] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [31] FALSE
書籍『時系列分析と状態空間モデルの基礎』での使用例
拙著『時系列分析と状態空間モデルの基礎:RとStanで学ぶ理論と実装』をお持ちの方はNipponパッケージを読み込む代わりに、source関数を実行してください。そうすれば、書籍と同じ結果を得ることができます。
p271からp273冒頭までのコードは以下のようになります。
# パッケージの読み込み
library(KFAS)
library(xts)
library(ggplot2)
library(ggfortify)
library(gridExtra)
# Nipponパッケージの代わりに、祝日判定関数を読み込む
source("https://raw.githubusercontent.com/logics-of-blue/website/master/010_forecast/20190714_R%E8%A8%80%E8%AA%9E%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E6%97%A5%E6%9C%AC%E3%81%AE%E7%A5%9D%E6%97%A5%E5%88%A4%E5%AE%9A/jholiday.R", encoding="utf-8")
# データの読み込み
file_data <- read.csv("https://raw.githubusercontent.com/logics-of-blue/book-tsa-ssm-foundation/master/book-data/5-11-sales_data.csv")
# xts型に変換
sales <- as.xts(read.zoo(file_data))
head(sales, n = 3)
# 日付の抽出
dates <- index(sales)
head(dates, n = 5)
# 祝日の判定
head(is.jholiday(dates))
## 以下略(書籍とまったく同じコードでOKです)
関数の仕組みの簡単な解説
当方の作成したis.jholiday関数は以下のようになっています。
長いように見えますが、ほとんどはコメントです。
(2020年10月2日追記)
文字コードが指定できるように修正しました。
is.jholiday <- function(target_date,
holiday_source = "https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv",
encoding = "CP932",
excluded_days = NULL,
flag = FALSE) {
# 日本の祝日を判定する関数。
# 初期状態では、『内閣府:「国民の祝日」について』というWebサイトで
# 提供されている祝日のデータを用いて祝日判定を行う。
# この場合はネット環境が必要。
#
# Args:
# target_date : 祝日判定の対象となる日付のベクトル
# holiday_source : 祝日判定の根拠となる祝日データ
# 1列目が祝日の日付、2列目が祝日の名称
# encoding : ファイルの文字コードを指定する文字列
# excluded_days : 除外する曜日のベクトル。その曜日は決して祝日とみなされない
# 「月・火・水・木・金・土・日」のいずれかを指定する
# flag : TRUEなら、0または1の数値型のベクトルを返す
# FALSEなら、論理値型のベクトルを返す
#
# Returns:
# 祝日判定の結果。target_dateと同じ長さのベクトル
# 対象となるベクトルを日付型にする
target_date <- as.Date(target_date)
# holiday_sourceをもとに祝日を取得
holidays <- read.csv(holiday_source, fileEncoding = encoding)
colnames(holidays) <- c("date", "holyday_name")
holidays$date <- as.Date(holidays$date)
# 祝日判定
if(is.null(excluded_days)) {
# すべての曜日で判定
result <- target_date %in% holidays$date
} else {
# 特定の曜日を除外
result <- (target_date %in% holidays$date) & !(weekdays(target_date, TRUE) %in% excluded_days)
}
if(flag) {
# 0または1のフラグにする
result <- as.numeric(result)
}
# 祝日判定の結果を返す
return(result)
}
処理についてはコメントを参照いただければ、ある程度理解できるかと思います。
『内閣府:「国民の祝日」について』というWebサイトから祝日が記録されたデータを読み込み、その結果と判定対象の日付を『%in%』を使ってマッチングさせています。
やり方はたくさんあるでしょうが、外部パッケージを使わなくて済むので、この方法にしています。
実は特定の曜日を除外したり、0か1のフラグで結果を返したりもできます。この辺りの使い方を次から解説します。
2.祝日判定をする関数の応用的な使い方
ネットに接続できない場合
『内閣府:「国民の祝日」について』というWebサイトが閲覧できればよいのですが、ネットに接続できていないこともあるでしょう。
この場合は、内閣府が提供してくれている祝日が入ったCSVファイルを自分のパソコンにダウンロードしておきます。
is.jholiday関数が実装された『jholyday.R』と、祝日が格納された『syukujitsu.csv』がともに『C:\data_folder』というフォルダにある場合は、以下のようなコードになります。
# 祝日判定関数の読み込み
source("C:/data_folder/jholiday.R", encoding="utf-8")
# 祝日判定をしたい日付データ
target_date <- seq(
from = as.Date("2019-05-01"),
to = as.Date("2019-5-31"),
by = 1
)
# 祝日判定
is.jholiday(target_date = target_date,
holiday_source = "C:/data_folder/syukujitsu.csv")
is.jholidayにholiday_sourceという名称で祝日ファイルのフルパスを指定すればよいです。
特定の曜日を除く
日曜日でかつ祝日、という場合は、わざわざ祝日扱いをしたくないときがあります。
日曜日を除いて祝日判定をする場合は『excluded_days = "日"』を指定します。5月1日は水曜日ですね。5月5日(日)がFALSEに変わったのがわかります。
> # 日曜日を除く > is.jholiday(target_date = target_date, + excluded_days = "日") [1] TRUE TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE [11] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [21] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [31] FALSE
土日をともに除く場合は以下のようにexcluded_daysに曜日のベクトルを指定します。
> # 土日を除く
> is.jholiday(target_date = target_date,
+ excluded_days = c("土", "日"))
[1] TRUE TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
[11] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[21] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[31] FALSE
0か1の祝日フラグを作る
統計モデルなどを構築する際、0か1の祝日フラグがほしいときがあります。
この場合は『flag = TRUE』を指定します。
> # 0か1のフラグで出力 > is.jholiday(target_date = target_date, + flag = TRUE) [1] 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [31] 0
拙著『時系列分析と状態空間モデルの基礎:RとStanで学ぶ理論と実装』では、日曜日を除く祝日に対して「1」となるフラグを作成していました。これは、以下のコードで達成できます。
> # 日曜日を除き、0か1のフラグで出力 > is.jholiday(target_date = target_date, + excluded_days = "日", + flag = TRUE) [1] 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [31] 0
参考文献
|
時系列分析と状態空間モデルの基礎: RとStanで学ぶ理論と実装 このブログの管理人が執筆した、時系列分析の入門書です。 時系列分析の基礎から、応用的な分析手法まで解説しています。 サポートページはこちらです。 |
|
更新履歴
2019年07月14日:新規作成
2020年10月02日:is.jholiday関数において、文字コードが指定できるように修正


source(“https://raw.githubusercontent.com/logics-of-blue/website/master/010_forecast/20190714_R%E8%A8%80%E8%AA%9E%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E6%97%A5%E6%9C%AC%E3%81%AE%E7%A5%9D%E6%97%A5%E5%88%A4%E5%AE%9A/jholiday.R”, encoding=”utf-8″)
target_date <- seq(
+ from = as.Date("2019-05-01"),
+ to = as.Date("2019-5-31"),
+ by = 1
+ )
is.jholiday(target_date = target_date)を実行すると
Error in make.names(col.names, unique = TRUE) : invalid multibyte string at '�Ex’
のエラーが出るのですが。
解決策を教えていただきたいです。
sssu様
コメントありがとうございます。
管理人の馬場です。
返信が遅れて申し訳ありません。
当方で確認したところ、エラーにはなりませんでした。
PCもしくはRやRStudioの設定が原因であるようです。
エラーメッセージを見ると、文字コードの問題のようです。
例えば、以下のコードを実行してからもう一度is.jholidayを再実行すると、うまくいくかもしれません。
options(encoding="Shift_JIS")