Подсчет количества дней, исключая воскресенья, между двумя датами и создание нового столбца в R DataFrame

#r #date-difference

#r #разница в дате

Вопрос:

У меня есть data.frame в R, в который входят две переменные с начальной и конечной датой. Я хотел бы добавить новый столбец с количеством дней между двумя датами и уменьшить результат на количество воскресений в каждом интервале. Я попробовал, как показано ниже, но это не работает:

 Data$Start <- as.Date(Data$Start, "%d.%m.%y")
Data$End <- as.Date(Data$End,"%d.%m.%y")

interval <- difftime(Data$Start, Data$End, units = "days")
sundays <- seq(from = Data$Start, to = Data$End, by = "days")
number.sundays <- length(which(wday(sundays)==1))

Data$DaysAhead <- interval - number.sundays
 

Я получаю сообщение об ошибке в функции seq (), что оно должно иметь длину 1, но я не понимаю, как я могу с этим справиться. Может ли кто-нибудь помочь мне с этим?

Ответ №1:

Вот пример, который работает:

 Data <- data.frame(
  Start = c("01.01.2020", "01.06.2020"), 
  End = c("01.03.2020", "01.09.2020")
)  

Data$Start <- as.Date(Data$Start, "%d.%m.%Y")
Data$End <- as.Date(Data$End,"%d.%m.%Y")

interval <- difftime(Data$End, Data$Start, units = "days")
sundays <- lapply(1:nrow(Data), function(i)seq(from = Data$Start[i], to = Data$End[i], by = "days"))
number.sundays <- sapply(sundays, function(x)length(which(lubridate::wday(x)==1)))

Data$DaysAhead <- interval - number.sundays
 

Проблема в том, что seq() он не векторизован, он предполагает единую начальную и единственную конечную точку. Если вы поместите его внутри цикла (например lapply() ), он будет работать и генерировать соответствующую последовательность для каждого времени начала и окончания. Затем вы можете использовать sapply() , чтобы выяснить, сколько воскресений и поскольку возвращаемое значение является скалярным, возвращаемым значением from sapply() будет вектор той же длины, interval что и .

Комментарии:

1. С помощью обновленного набора данных я понял, что существует проблема с решением выше, когда начальная и конечная даты не совпадают в один и тот же год. Я все еще хочу подсчитать дни, кроме воскресенья, начиная с 20.12.2020 до 10.01.2021, например.

2. прошу прощения, в формате даты это должна быть заглавная буква «Y» "%d.%m.%Y" . Если вы измените это в приведенных выше командах форматирования начальной и конечной даты, это сработает. Я отредактировал ответ, чтобы устранить проблему.

Ответ №2:

С помощью обновленного набора данных я понял, что существует проблема с решением выше, когда начальная и конечная даты не совпадают в один и тот же год. Я все еще хочу подсчитать дни, кроме воскресенья, начиная с 20.12.2020 до 10.01.2021, например. В этом случае появляется сообщение об ошибке, заключающееся в том, что знак с аргументом «by» неверен. Я просто не могу запустить его. Если я переверну даты, вывод не имеет смысла, а количество дней слишком велико. Что мне нужно сделать, чтобы запустить это до конца года?