

R言語で土日祝日を除いた日数の計算に使用できる関数はありますか？
引数に「開始日」「終了日」を指定すると、その期間の日数を計算するようなイメージです。祝日データは手動で用意する前提です。


CC BY-SA 3.0
2016-10-23T13:23:38.680
29838
2016-10-24T07:27:17.703
2016-10-23T13:33:19.127
19201
19201
question
r
R言語で土日祝日を除いた日数の計算


祝日のデータをどの様に保持しているのか不明ですが、ここでは年月日を表す文字列のベクタだとします。

[code]

    # 2016年の場合、3月21日が振替休日になっていますが、それは含めていません
    > holidays = c("2016/1/1", "2016/1/11", "2016/2/11", "2016/3/20", "2016/4/29", 
                   "2016/5/3", "2016/5/4", "2016/5/5", "2016/7/18", "2016/8/11", 
                   "2016/9/19", "2016/9/22", "2016/10/10", "2016/11/3", "2016/11/23", 
                   "2016/12/23")
    
    # 2016年1月1日から2016年10月23日までのシーケンス(1日単位)を作成
    > s = seq.Date(as.Date("2016/1/1"), as.Date("2016/10/23"), by="day")
    # format(s, "%u") は曜日を数値で返します。月曜日が 1、日曜日が 7 になります
    > length(s[format(s, "%u") < 6 & !format(s, "%Y/%-m/%-d") %in% holidays])
    [1] 199
    
[/code]


CC BY-SA 3.0
2016-10-23T14:51:32.530
29845
2016-10-23T15:03:54.967
2016-10-23T15:03:54.967
29838
answer


`timeDate`パッケージには平日・週末を識別する関数`isWeekday()`があります、また日本を始めとするG7の祝日データも保有しています...が投稿後に漏れがあることに気づきました、使わないほうがよいでしょう。代わりに`Nippon`パッケージの`jholiday()`関数で祝日データを獲得しています。

[code]

    library(timeDate); library(Nippon)
    
     ## metropolis様のコードを利用させていただいております
    days = seq.Date(as.Date("2016/1/1"), as.Date("2016/10/23"), by="day")
    
     ## 2016年の祝日情報を格納
    hol2016 <- jholiday(2016)
    
     ## 判別
    weekday <- days[isWeekday(days)]                # まずはじめに週末を除外
    heijitu <- weekday[! weekday %in% hol2016]      # 次に祝日を除外
    length(heijitu)                                 # 何日あるかチェック
     # [1] 198      # metropolis様とのズレは3月21日の振り替え休日に起因しています
    
[/code]

**EDITED** (関数化)

2000年以降に対応。最初に複数年の祝日を`jholiday`に`Vectorize()`を用いて取得していますが、その関係で`as.numeric()`されてしまうため、`as.Date()`で`Date`に戻しています。

[code]

    heijitu.f <- function(start, end) {
      hol2000_2016 <- as.Date(unlist(Vectorize(Nippon::jholiday, "year")(2000:2016)), origin = "1970-1-1")
      days <- seq.Date(as.Date(start), as.Date(end), by="day")
      result <- length(days[timeDate::isWeekday(days) &! (days %in% hol2000_2016)])
      return(result)
    }
    
    heijitu.f("2016/01/01", "2016/10/23")
     # [1] 198
    
[/code]


CC BY-SA 3.0
2016-10-23T16:43:32.907
29848
2016-10-24T07:27:17.703
2016-10-24T07:27:17.703
15653
15653
29838
answer