itthrill
itthrill

Reputation: 1376

adding months properly in R

I am trying to add 15 months to an existing date. However the result is not proper end of month which is expected from using %m+% in lubridate.

> as.Date("2018-04-30") %m+% months(15)
[1] "2019-07-30"

Upvotes: 0

Views: 416

Answers (2)

IRTFM
IRTFM

Reputation: 263481

You could use the yearmon class in the zoo package. I think it is better thought out for this purpose than the lubridate functions appear to be. You would not need to separately calculate the extra days. Notice that additon of months needs to be in years so divide the months by 12. The frac=1 as argument to as.Date.yearmon returns the last day of the month:

library(zoo)
as.Date( as.yearmon( as.Date("2018-04-30") ) +15 , frac=1)
[1] "2033-04-30"    Wrong!!!
# Divided months by 12
as.Date( as.yearmon( as.Date("2018-04-30") ) +15/12 , frac=1)
[1] "2019-07-31"   Success

Upvotes: 0

r2evans
r2evans

Reputation: 161110

The %m+% simply adds the months, at no point is there an assumption that it will maintain the "last day of the month" status. As @duckmayr succinctly stated, it protects against exceeding the end of the month, but I believe it should not be a safe assumption to infer it should push out accordingly.

Alternatives:

rollback(as.Date("2018-04-30") %m+% months(15+1))
# [1] "2019-07-31"

ceiling_date(as.Date("2018-04-30") %m+% months(15), unit="month") - 1
# [1] "2019-07-31"

ceiling_date(as.Date("2018-04-30") %m+% months(15), unit="month") %m+% days(-1)
# [1] "2019-07-31"

And perhaps some further combinations.

Upvotes: 2

Related Questions