首先检查日期是否真的是工作日;如果是周末或节假日返回-1(不要带字符串,否则输出为字符)。
否则,从相应月份的01 开始的seq.Date 到相应的日期,删除以S 开始的weekdays 以及那些在假期定义向量h 中的那些(如果已定义) .
实际上,R 可以在不使用任何包的情况下做到这一点,而且速度要快得多。
因此,我们可以像这样定义Vectorized 函数:
f <- Vectorize(\(d, h=NULL) {
stopifnot(inherits(d, c('Date')))
stopifnot(inherits(h, c('Date', 'NULL')))
if (grepl('S', weekdays(d)) | d %in% h) {
return(-1L)
} else {
s <- seq.Date(as.Date(paste0(substr(d, 1, 7), '-01')), d, 1L)
return(length(s[!grepl('S', weekdays(s)) & !s %in% h]))
}
}, vectorize.args='d')
f(dates)
# [1] 10 21 20 -1
f(dates, holydays)
# [1] 10 21 18 -1
注意:使用 R >= 4.1。
请注意,在 R 中,您应该始终使用所需的日期格式,并且可能需要先进行转换:
dates <- as.Date(c("12/14/2021", "01/31/2022"), format='%m/%d/%Y')
如果星期六是工作日,请在grepl 中使用'Su',或者在您的区域设置中使用'Sunday',只需尝试weekdays(dates)。
数据:
dates <- as.Date(c("2022-12-14", "2022-01-31", "2022-04-28", "2022-12-31"))
holydays <- as.Date(c("2022-01-01", "2022-04-15", "2022-04-18", "2022-05-01",
"2022-05-26", "2022-06-06", "2022-08-01", "2022-12-25",
"2022-12-26"))