R语言开发捷克地区下一个最近工作日查询函数的技术问询
Got it, let's fix your next business day calculation! The core problem with your current code is that next_business_dt simply adds 1 day without accounting for weekends, holidays, or even consecutive stretches of non-working days. Here's a robust approach that handles all these edge cases:
Step 1: Define Helper Functions
First, let's create a helper function to check if a given date is a valid business day (non-weekend + non-holiday):
library(dplyr) library(lubridate) # Your holiday list 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") # Helper function: Check if a date is a business day is_business_day <- function(date) { # Rule 1: Exclude weekends (wday() returns 1=Sunday, 7=Saturday) if (wday(date) %in% c(1, 7)) { return(FALSE) } # Rule 2: Exclude non-weekend holidays if (format(date, "%m-%d") %in% business_holidays) { return(FALSE) } # If neither, it's a business day return(TRUE) }
Next, create the main function to find the next business day starting from the day after your input date:
# Main function: Get the next nearest business day get_next_business_day <- function(start_date) { next_day <- start_date + days(1) # Keep incrementing the day until we hit a valid business day while (!is_business_day(next_day)) { next_day <- next_day + days(1) } return(next_day) }
Step 2: Apply to Your Dataset
Now you can integrate this into your existing dataframe to calculate next_business_dt correctly:
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), # Use our function to get the correct next business day next_business_dt = purrr::map(date, get_next_business_day) %>% as.Date() )
Step 3: Test Edge Cases
Let's verify this works for your examples and tricky scenarios:
- For
2019-07-09:get_next_business_day(as.Date("2019-07-09"))returns2019-07-10(correct, since it's a weekday and not a holiday) - For
2019-07-04: The next day is2019-07-05(holiday), followed by2019-07-06(another holiday) — the function skips both and returns2019-07-08(the next valid Monday) - For
2019-12-23: The function skips2019-12-24,2019-12-25,2019-12-26(all holidays) and returns2019-12-27(the next Friday)
This approach handles any number of consecutive non-working days, whether they're weekends, holidays, or a mix of both.
内容的提问来源于stack exchange,提问作者user4394417

