Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to subtract months from a date in R?

Tags:

r

I'm trying to subtract n months from a date as follows:

maturity <- as.Date("2012/12/31")  m <- as.POSIXlt(maturity)  m$mon <- m$mon - 6 

but the resulting date is 01-Jul-2012, and not 30-Jun-2012, as I should expect. Is there any short way to get such result?

Thanks in advance

like image 463
user648905 Avatar asked Mar 07 '11 22:03

user648905


People also ask

How do I get previous month in R?

The last date of the month in R You can do it with the ceiling_date function from lubridate. If you use it by itself, then you will get the first date of next month. With simple subtraction, you can gate the last date of a given month.

How do I get the year from a date in R?

To get the year from a date in R you can use the functions as. POSIXct() and format() . For example, here's how to extract the year from a date: 1) date <- as. POSIXct("02/03/2014 10:41:00", format = "%m/%d/%Y %H:%M:%S) , and 2) format(date, format="%Y") .


1 Answers

1) seq.Date. Note that June has only 30 days so it cannot give June 31st thus instead it gives July 1st.

seq(as.Date("2012/12/31"), length = 2, by = "-6 months")[2] ## [1] "2012-07-01" 

If we knew it was at month end we could do this:

seq(as.Date(cut(as.Date("2012/12/31"), "month")), length=2, by="-5 month")[2]-1 ## "2012-06-30" 

2) yearmon. Also if we knew it was month end then we could use the "yearmon" class of the zoo package like this:

library(zoo) as.Date(as.yearmon(as.Date("2012/12/31")) -.5, frac = 1) ## [1] "2012-06-30" 

This converts the date to "yearmon" subtracts 6 months (.5 of a year) and then converts it back to "Date" using frac=1 which means the end of the month (frac=0 would mean the beginning of the month). This also has the advantage over the previous solution that it is vectorized automatically, i.e. as.Date(...) could have been a vector of dates.

Note that if "Date" class is only being used as a way of representing months then we can get rid of it altogether and directly use "yearmon" since that models what we want in the first place:

as.yearmon("2012-12") - .5 ## [1] "Jun 2012" 

3) mondate. A third solution is the mondate package which has the advantage here that it returns the end of the month 6 months ago without having to know that we are month end:

library(mondate) mondate("2011/12/31") - 6 ## mondate: timeunits="months" ## [1] 2011/06/30 

This is also vectorized.

4) lubridate. This lubridate answer has been changed in line with changes in the package:

library(lubridate) as.Date("2012/12/31") %m-% months(6) ## [1] "2012-06-30" 

lubridate is also vectorized.

5) sqldf/SQLite

library(sqldf) sqldf("select date('2012-12-31', '-6 months') as date") ##         date ## 1 2012-07-01 

or if we knew we were at month end:

sqldf("select date('2012-12-31', '+1 day', '-6 months', '-1 day') as date") ##         date ## 1 2012-06-30 
like image 112
G. Grothendieck Avatar answered Sep 23 '22 22:09

G. Grothendieck