Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 计算表中按月份分组的给定两个日期之间的天数_R - Fatal编程技术网

R 计算表中按月份分组的给定两个日期之间的天数

R 计算表中按月份分组的给定两个日期之间的天数,r,R,我有一套开始和结束日期。我必须计算每月的天数,不包括周末和国定假日。输出数据显示在此处: 代码变得太复杂,无法给出正确的结果 我尝试的代码是: sd ="24-Jan-18" ed ="4-Mar-18" sd_m <- ymd(strptime(as.character(sd), format = "%d-%b-%y")) ed_m <- ymd(strptime(as.character(ed), format = "%d-%b-%y")) s_m <- format(s

我有一套开始和结束日期。我必须计算每月的天数,不包括周末和国定假日。输出数据显示在此处:

代码变得太复杂,无法给出正确的结果

我尝试的代码是:

sd ="24-Jan-18"
ed ="4-Mar-18"
sd_m <- ymd(strptime(as.character(sd), format = "%d-%b-%y"))
ed_m <- ymd(strptime(as.character(ed), format = "%d-%b-%y"))
s_m <- format(sd_m, "%b-%Y")
  e_m <-  format(ed_m, "%b-%Y")
  no_months<- (year(ed_m) - year(sd_m)) * 12 + month(ed_m) - month(sd_m) +1
  i = 0
  day_count = as.vector(0)
  e_mon = as.Date(seq(as.yearmon(sd_m),as.yearmon(ed_m),1/12),frac = 1)
  s_mon =   as.Date(seq(as.yearmon(sd_m),as.yearmon(ed_m),1/12),frac = 0)
  day_count[1]= = sum(!weekdays(seq(sd_m ,e_mon[1], "days")) %in% c('Saturday', 'Sunday')) -holiday
  i=2
  for (i in 1:(no_months-1)){
   day_count[i]= sum(!weekdays(seq(s_mon[i], e_mon[i], "days")) %in% c('Saturday', 'Sunday')) -holiday } 
  day_count[no_months] = sum(!weekdays(seq(s_mon[no_months],ed_m, "days")) %in% c('Saturday', 'Sunday')) -holiday

请帮忙建造

Tidyverse方法,使用一些润滑功能

sd ="2018-01-24"
ed ="2018-03-04"

#create a data.frame with all days from startdata (sd) to end date (ed)
df <- data.frame( dates = seq( as.Date(sd), as.Date(ed), by = "days"))

#create the vector with Holiday-dates
holidays_v <- as.Date( c("2018-01-26", "2018-05-01", "2018-08-15", "2018-09-13", "2018-10-02", "2018-12-25") )

library(tidyverse)

df %>% 
  #filter out all days that are Sundays (wday == 1), or Saturdays (wday == 7), of within the vector with Holidays
  filter( !lubridate::wday( dates ) %in% c(1,7) & !dates %in% holidays_v ) %>%
  #create period to summarise by (here: year-month)
  mutate( period = paste( lubridate::year(dates), formatC(lubridate::month(dates), width = 2, format = "d", flag = "0"), sep = "-") ) %>%
  # group by period
  group_by( period ) %>%
  #... and summarise
  summarise( number = n() )

# # A tibble: 3 x 2
#   period  number
#   <chr>    <int>
# 1 2018-01      5
# 2 2018-02     20
# 3 2018-03      2
sd=“2018-01-24”
ed=“2018-03-04”
#创建一个data.frame,其中包含从开始日期(sd)到结束日期(ed)的所有天数
df%
#创建要汇总的期间(此处:年-月)
变异(期间=粘贴(lubridate::年(日期),格式C(lubridate::月(日期),宽度=2,格式=“d”,标志=“0”),九月=“-”)%%>%
#按时段分组
分组单位(期间)%>%
#... 总结
摘要(编号=n())
##tibble:3 x 2
#周期数
#       
# 1 2018-01      5
# 2 2018-02     20
# 3 2018-03      2

这是一个基本解决方案。使用末尾注释中重复显示的输入创建一个数据框
d
,每个日期一行,并从中删除周末和假日。然后按年份和月份进行汇总。这被应用到输入的每一行,给出一个数据帧列表,这些数据帧被合并在一起。最后,它被转换为广域形式。如果格式为yyyy mm的列名正常,则可以省略代码的最后一行

toLong <- function(row, sd, ed, hol) {
  s <- seq(sd, ed, "day")
  d <- data.frame(row, s, ym = format(s, "%Y-%m"))
  d <- subset(d, ! weekdays(s) %in% c("Saturday", "Sunday"))
  d <- subset(d, ! s %in% hol)
  data.frame(row, sd, ed, aggregate(s ~ ym, d, FUN = length))
}

L <- Map(toLong, 1:nrow(DF), DF$sd, DF$ed, MoreArgs = list(hol = hol))
DF2 <- do.call("rbind", L)
xt <- xtabs(s ~ row + ym, DF2)
DF3 <- cbind(DF, as.data.frame.matrix(xt))
names(DF3)[-(1:2)] <- format(as.Date(paste0(names(DF3)[-(1:2)], "-01")), "%b %Y")
笔记 可从中复制的输入为:

DF <-
  structure(list(sd = structure(c(17805, 17555), class = "Date"), 
    ed = structure(c(17836, 17594), class = "Date")), row.names = c(NA, 
  -2L), class = "data.frame")

hol <- as.Date(c("2018-01-26", "2018-05-01", "2018-08-15", "2018-09-13", 
  "2018-10-02", "2018-12-25"))

DF谢谢你的回答!但我仍然有疑问。2018-01年的值应为5。因为2018年1月27日和2018年1月28日是周末,根据我的假日清单,2018年1月26日是假日。因此,总工作日为5天。我不知道为什么这个过滤器不起作用,
>df$dates[3][1]“2018-01-26”>假日[1][1]“2018-01-26”>df$dates[3]==假日[1][1]TRUE>df$dates%in%holidays\u v(给出所有假值)
@user2601604我编辑了我的答案。。现已修复,结果如您的数据所示。谢谢您的回答。但对你来说也是如此。这不是减去假日。一月应该是5天。增加了假期。
> DF3
          sd         ed Oct 2018 Nov 2018 Jan 2018 Feb 2018 Mar 2018
1 2018-10-01 2018-11-01       23        1        0        0        0
2 2018-01-24 2018-03-04        0        0        6       20        2
DF <-
  structure(list(sd = structure(c(17805, 17555), class = "Date"), 
    ed = structure(c(17836, 17594), class = "Date")), row.names = c(NA, 
  -2L), class = "data.frame")

hol <- as.Date(c("2018-01-26", "2018-05-01", "2018-08-15", "2018-09-13", 
  "2018-10-02", "2018-12-25"))