R-查找最近的工作日(捷克)

时间:2019-07-09 09:21:57

标签: r lubridate

我需要创建一个函数,该函数将返回下一个最近的工作日。对于今天(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年,有一个周末,然后是圣诞节前三天假期。

1 个答案:

答案 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的最后几行中。例如,如果我们将日期序列扩展到明年的某几天然后削减结果,则可能会得到解决。