Reputation: 3047
I have a function that can add one day to a date. In case the following date is on Saturday/Sunday/bank holiday, the function calls itself with the argument date = date + 1 from the previous function call. Now I would like to extend the function so that it allows for adding n days (instead of 1 day that works currently). I would like to use functional programming/recursion to do that if possible.
# 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"
Upvotes: 1
Views: 138
Reputation: 3047
This seems to achieve what I need using recursion.
# 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"
Upvotes: 1