Вот базовое решение. Использование входных данных, воспроизводимых в примечании в конце toLong
, создает фрейм данных d
с одной строкой на дату и удаляет из нее выходные и праздничные дни. Затем он агрегирует это по годам и месяцам. Это применяется к каждой строке ввода, давая список L
фреймов данных, которые rbind
объединены вместе. Наконец, это преобразуется в широкую форму. Последняя строка кода может быть опущена, если имена столбцов в формате гггг-мм в порядке.
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")
дает:
> 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"))