R - 使用 lubridate 从时间间隔计算中排除周末

R - exclude weekends from time interval calculations with lubridate

我想计算日期之间的间隔。天数差异应考虑周末。我有 200 多个日期戳。

例如目前显示的1月5日(周二)与1月11日(周一)的时差为5天。我想获得3天。

我可以通过以下代码和包 lubridatedplyr.

在不排除周六和周日的情况下找到解决方案

能否指导我如何排除周末进行计算? 谢谢。

library(lubridate)
library(dplyr)


dates <- c("2021-01-01", "2021-01-04", "2021-01-05", "2021-01-06", "2021-01-11", "2021-01-13", "2021-01-14", "2021-01-18", "2021-01-25", "2021-01-29")

d <- do.call(rbind, lapply(dates, as.data.frame))

dateoverview <- rename(d, Dates = 1)

dateoverview$Dates <- lubridate::ymd(dateoverview$Dates)

datecalculation <- dateoverview %>%
                   mutate(Days = Dates - lag(Dates)) %>% 
                   mutate(Weekday = wday(Dates, label = FALSE))

datecalculation


##         Dates    Days Weekday
## 1  2021-01-01 NA days       6
## 2  2021-01-04  3 days       2
## 3  2021-01-05  1 days       3
## 4  2021-01-06  1 days       4
## 5  2021-01-11  5 days       2
## 6  2021-01-13  2 days       4
## 7  2021-01-14  1 days       5
## 8  2021-01-18  4 days       2
## 9  2021-01-25  7 days       2
## 10 2021-01-29  4 days       6


可能某处已经有一个函数在执行此操作,但这里有一个自定义函数可以帮助您计算不包括周末的日期差异。

library(dplyr)
library(purrr)

date_diff_excluding_wekeends <- function(x, y) {
  if(is.na(x) || is.na(y)) return(NA)
  sum(!format(seq(x, y - 1, by = '1 day'), '%u') %in% 6:7)
}

datecalculation %>%
  mutate(Days = map2_dbl(lag(Dates), Dates, date_diff_excluding_wekeends))

#        Dates Days Weekday
#1  2021-01-01   NA       6
#2  2021-01-04    1       2
#3  2021-01-05    1       3
#4  2021-01-06    1       4
#5  2021-01-11    3       2
#6  2021-01-13    2       4
#7  2021-01-14    1       5
#8  2021-01-18    2       2
#9  2021-01-25    5       2
#10 2021-01-29    4       6
  • seq(x, y - 1, by = '1 day') 在前一个日期和当前日期之间创建一个日期序列 - 1.
  • format(..., "%u") returns 星期几。 1 代表周一,7 代表周日。
  • 我们使用 sum(!format(...) %in% 6:7) 计算工作日的天数。

另一个可能的解决方案:

library(lubridate)

# sample data
df = data.frame(Dates = seq(ymd('2021-01-01'),ymd('2021-12-31'),by='days'))
df_weekdays = df %>% filter(!(weekdays(as.Date(df$Dates)) %in% c('Saturday','Sunday')))

#Application to your data 
datecalculation =   datecalculation %>% 
    filter(!(weekdays(as.Date(datecalculation$Dates)) %in% c('Saturday','Sunday')))