Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

confusion over how duration vs. periods work in lubridate with month addition

Tags:

date

r

lubridate

Here is what I think is a possible bug:

require(lubridate)
d = as.Date("1994-03-31")
> d + months(1)
  [1] "1994-05-01"

My understanding is that this should return the end of month 4 of year 1994. Please advise if this is indeed a bug.

like image 988
Alex Avatar asked Feb 18 '23 11:02

Alex


1 Answers

It is not a bug, it is a documented feature. It is definitely not a bug in lubridate as months and as.Date are both base package functions. . (Edit. months.numeric and months.integer are both non-visible functions from the lubridate package.

However, luibridate does have an answer!

It is doing exactly as specified in the help file for %m+% (which is part of the lubridate package.)

Adding months frustrates basic arithmetic because consecutive months have different lengths. With other elements, it is helpful for arithmetic to perform automatic roll over. For example, 12:00:00 + 61 seconds becomes 12:01:01. However, people often prefer that this behavior NOT occur with months. For example, we sometimes want January 31 + 1 month = February 28 and not March 3. months(n) always returns a date in the nth month after Date. If the new date would usually spill over into the n + 1th month, month. Date nth month before Date.

The function %m+% is designed to ensure the feature you want, ensuring that the month isn't rolled over

d %m+% months(1)

## [1] "1994-04-30" 

Note that this feature was introduced in version 1.2.0, and thus is not documented in http://www.jstatsoft.org/v40/i03/paper, as this was written prior to the implementation

Also note that you could also use duration(1, 'months')

 d + duration(1, 'months')
 ## [1] "1994-04-30" 
like image 130
mnel Avatar answered Apr 26 '23 08:04

mnel