我需要创建一个函数,该函数将返回下一个最近的工作日。对于今天(2019-07-09
),结果将是2019-07-10
,因为明天不是工作假期或周末。如果明天是工作假期,则结果应为2019-07-11
,但如果该天是周末/假日,则结果应为最近的工作日。
这里是本地工作假期的列表。在四月的这两天之间,复活节前夕和日期是可变的,但是以后我会自行修复。
business_holidays <- c("01-01", "04-19", "04-22", "05-01", "05-08", "07-05", "07-06",
"09-28", "10-28", "11-17", "12-24", "12-25", "12-26")
这是我创建的。
library(dplyr)
library(lubridate)
df <- data.frame(
date=seq(as.Date("2019-01-01"), as.Date("2019-12-31"), "days")
) %>%
mutate(
weekend = if_else(wday(date) %in% c(7, 1), 1, 0),
business_holiday = if_else(
format(date, "%m-%d") %in% business_holidays & weekend == 0,
1, 0),
next_business_dt = date + 1
)
next_business_dt
不正确,因为第二天可能是周末(1或2天),而最近的星期一可能是商务假期。这些工作假期可能不止一天,例如圣诞节前夕-在2017年,有一个周末,然后是圣诞节前三天假期。
答案 0 :(得分:0)
一种可能的解决方案是使用fill()
包的tidyr
函数。
首先,如果是工作日,请在next_business_dt
列中填写日期,如果该日对应于周末或假日,则用NA填充:
library(dplyr)
library(lubridate)
library(tidyr)
df <- data.frame(
date = seq(as.Date("2019-01-01"), as.Date("2019-12-31"), "days")
) %>%
mutate(
weekend = if_else(wday(date) %in% c(7, 1), 1, 0),
business_holiday = if_else(
format(date, "%m-%d") %in% business_holidays & weekend == 0,
1, 0),
next_business_dt = ifelse((weekend | business_holiday),
NA, format(date, "%Y-%m-%d")
)
)
然后用最接近的下一个非NA日期填充next_business_dt
列:
res <- df %>% fill(next_business_dt, .direction = "up")
它的工作原理是:
date weekend business_holiday next_business_dt 1 2019-01-01 0 1 2019-01-02 2 2019-01-02 0 0 2019-01-02 3 2019-01-03 0 0 2019-01-03 4 2019-01-04 0 0 2019-01-04 5 2019-01-05 1 0 2019-01-07 6 2019-01-06 1 0 2019-01-07 7 2019-01-07 0 0 2019-01-07
尽管,如果一年中的最后一天或一天不是工作日(2017年就是这种情况),则NA将保留在next_business_dt
的最后几行中。例如,如果我们将日期序列扩展到明年的某几天然后削减结果,则可能会得到解决。