Вычитание месяцев - проблема с последним днем ​​месяца?

Быстрый вопрос о датах в R. Посмотрите этот фрагмент кода:

Sys.Date() - months(3)
# [1] "2013-12-31"
Sys.Date() - months(18)
# [1] NA

Я загрузил пакет lubridate и подписался на предоставленные инструкции, и я не могу понять это поведение. Раньше он работал нормально, сегодня первый день, когда я заметил, что вычитание более 12 месяцев из сегодняшней даты дает NA (вычитание менее 12 месяцев работает нормально).

Буду признателен, если кто-нибудь сможет объяснить мне, почему это не работает, и / или предложить более «надежный» способ решения этой проблемы. Имеет ли это какое-то отношение к тому, что сегодня последний день месяца (31-й день)?

Я спрашиваю, потому что это работает:

Sys.Date() - years(2)
# [1] "2012-03-31"

person PMaier    schedule 31.03.2014    source источник
comment
Это действительно 31-е число в этом месяце? выпуск: lapply(1:18, function(x) Sys.Date()-months(x))   -  person tonytonov    schedule 31.03.2014
comment
К обходным путям относятся: seq(Sys.Date(), length = 2, by = "-18 months") или library(mondate); as.Date(as.mondate(Sys.Date()) - 18), которые разрешают неоднозначность двумя разными способами.   -  person G. Grothendieck    schedule 31.03.2014
comment
Если вы ищете решение, ориентированное на ежемесячные данные, также ознакомьтесь с library(xts); as.yearmon(Sys.Date()) - 1:18/12   -  person tonytonov    schedule 31.03.2014


Ответы (3)


Функции lubridate %m+% и %m-% предназначены для решения этой проблемы («Добавить и вычесть месяцы к дате, не превышая последний день нового месяца»).

library(lubridate)
Sys.Date() %m-% months(18)
# [1] "2012-09-30"

# or to make it reproducible if Sys.Date() happens to be different from that in OP
as.Date("2014-03-31") %m-% months(18)
# [1] "2012-09-30"

# example of %m+%
as.Date("2014-01-31") + months(1)
# [1] NA
as.Date("2014-01-31") %m+% months(1)
# [1] "2014-02-28"
person Henrik    schedule 31.03.2014

Решение предоставляет ожидаемые месяцы точно, то есть 28Feb% m +% дает 28Mar, что не идеально для работы с данными на конец месяца.

Чтобы настроить верхнюю границу так, чтобы всегда отображался последний день месяца, используйте следующий код:

ceiling_date((as.Date("2014-02-28") %m+% months(1)),"month")-days(1)

> "2014-03-31"
person Nick    schedule 26.11.2015

Точно так же, если вы хотите получить прирост на 3 месяца, это можно сделать следующим образом:

PW_Data_Plan_V1$Month = as.Date(PW_Data_Plan_V1$DOJ) %m+% months(3)
person AnksG    schedule 23.05.2017