首页 > 解决方案 > R递归函数将n天添加到跳过星期六/星期日和银行假日的日期

问题描述

我有一个可以在日期中添加一天的功能。如果下一个日期是星期六/星期日/银行假日,则该函数使用上一个函数调用的参数 date = date + 1 调用自身。现在我想扩展该功能,以便它允许添加 n 天(而不是当前工作的 1 天)。如果可能的话,我想使用函数式编程/递归来做到这一点。

# simplified for only 1 bank holiday on 22nd January (in reality, there are more bank holidays)
# simplified to only allow to add one day
# want to add n day(s) skipping bank holiday(s) and Saturdays/Sundays
next_bus_day_simplified <- function(.date = ymd("2021-01-21")){
  
  following_date <- .date + 1
  
  df <- data.frame(following_date) %>%
    mutate(
      following_date = case_when(
        wday(following_date, week_start = 1) %in% c(6, 7) ~ NA_Date_,
        day(following_date) ==  22 & month(following_date) ==  1 ~ NA_Date_,
        T ~ following_date
      )
    )
  
  return(
    if(!is.na(df$following_date)){ df$following_date }else{next_bus_day_simplified(following_date)}
  )
  
}

next_bus_day_simplified()
# [1] "2021-01-25"

标签: rdaterecursionfunctional-programming

解决方案


这似乎使用递归实现了我所需要的。

# simplified for only 1 bank holiday on 22nd January (in reality, there are more bank holidays)
# allows to add n day(s) skipping bank holiday(s) and Saturdays/Sundays
next_bus_day_simplified <- function(.date, .n){
  
  .n <- .n - 1
  following_date <- .date + 1
  
  df <- data.frame(following_date) %>%
    mutate(
      following_date = case_when(
        wday(following_date, week_start = 1) %in% c(6, 7) ~ NA_Date_,
        day(following_date) ==  22 & month(following_date) ==  1 ~ NA_Date_,
        T ~ following_date
      )
    )
  
  if(is.na(df$following_date)){
    Recall(following_date, .n + 1) # the following day is 
  }
  else if(!is.na(df$following_date) & .n > 0){
    Recall(following_date, .n = .n)
  }
  else if(!is.na(df$following_date) & .n == 0){
    return(df$following_date)
  }
  else{
    print("unexpected!!!!")
  }
}

next_bus_day_simplified(ymd("2021-01-20"), .n = 2)
# [1] "2021-01-25"

推荐阅读