R言語における日本の祝日判定

Rにおいて日本の祝日を判定する方法を解説します。
『内閣府:「国民の祝日」について』で提供されている祝日のデータを用いて祝日判定を行います。

いままでNipponパッケージを使って祝日判定をする方法を紹介してきました。しかしNipponパッケージが2019年7月現在、使用できなくなっています。
祝日判定をするだけでしたら、比較的短いコードで実装が可能です。この記事ではパッケージを使わずに祝日判定を行います。

なお拙著『時系列分析と状態空間モデルの基礎:RとStanで学ぶ理論と実装』においてもNipponパッケージを用いています。
こちらの書籍をお持ちの方は、Nipponパッケージを使う代わりに、この記事で紹介されている方法を用いてください。

『内閣府:「国民の祝日」について』で提供されているデータを使用しています。こちらのページのURLが変更されてコードが動かなくなった等の問題があれば、コメントなどでお知らせいただけますと幸いです。

コードはすべてGitHubで公開しています
当方で簡単な動作確認を行いましたが、結果を保証するものではありません。参考程度にお使いください。
何か問題があれば、コメントなどでお知らせいただけますと幸いです。

目次

  1. 祝日判定をする関数の基本的な使い方
    1. 基本的な使い方
    2. 書籍『時系列分析と状態空間モデルの基礎』での使用例
    3. 関数の仕組みの簡単な解説
  2. 祝日判定をする関数の応用的な使い方
    1. ネットに接続できない場合
    2. 特定の曜日を除く
    3. 0か1の祝日フラグを作る

 

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関数において、文字コードが指定できるように修正

R言語における日本の祝日判定” に対して2件のコメントがあります。

  1. sssu より:

    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’
    のエラーが出るのですが。
    解決策を教えていただきたいです。

    1. 馬場真哉 より:

      sssu様

      コメントありがとうございます。
      管理人の馬場です。

      返信が遅れて申し訳ありません。

      当方で確認したところ、エラーにはなりませんでした。
      PCもしくはRやRStudioの設定が原因であるようです。

      エラーメッセージを見ると、文字コードの問題のようです。

      例えば、以下のコードを実行してからもう一度is.jholidayを再実行すると、うまくいくかもしれません。


      options(encoding="Shift_JIS")

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください