rajvijay
rajvijay

Reputation: 1721

Adding quarters to R date

I have a R time series data, where I am calculating the means for all values up to a particular date, and storing this means in the date + 4 quarters. The dates are all month ends. To achieve this, I am looking to increment 4 quarters to a date. My question is how can I add 4 quarters to an R date data-type. An illustration:

a <- as.Date("2006-01-01")
b <- as.Date("2011-01-01")
date_range <- quarter(seq.Date(a, b, by = "quarter"), with_year = TRUE)

> date_range[1] + 1
[1] 2007.1

> date_range[1] + quarter(1)
[1] 2007.1

> date_range[1] + 0.25
[1] 2006.35

One possible way I am thinking is to get year-quarter dates, and then adding 4 to it. But wasn't sure what is the best way to do this?

Upvotes: 2

Views: 9062

Answers (5)

G. Grothendieck
G. Grothendieck

Reputation: 269654

Note that other answers that use Date class will give irregularly spaced series and so are unsuitable for time series analysis.

To do this in such a way that time series analyses can be performed and noting the zoo tag on the question, the yearmon class represents year/month as year + fraction where fraction is 0 for Jan, 1/12 for Feb, 2/12 for Mar, ..., 11/12 for Dec. Thus adding 4 quarters is just a matter of adding 1. (Adding x quarters is done by adding x/4.)

library(zoo)
ym <- yearmon(2006) + 0:11/12   # months in 2006
ym + 1 # one year later

Also this converts yearmon objects to end-of-month Date and in the second line Date to yearmon. Using frac = 0 or omitting frac in the first line would convert to beginning of month dates.

d <- as.Date(ym, frac = 1)  # d is Date vector of end-of-months
as.yearmon(d)  # convert Date vector to yearmon

If your input dates represent quarters then there is also the yearqtr class which represents a year/quarter as year + fraction where fraction is 0, 1/4, 2/4, 3/4 for the 4 quarters of a year. Adding 4 quarters is done by adding 1 (or to add x quarters add x/4).

yq <- as.yearqtr(2006) + 0:3/4   # all quarters in 2006
yq + 1  # one year later

Conversions work similarly to yearmon:

d <- as.Date(ym, frac = 1)  # d is Date vector of end-of-quarters
as.yearqtr(d)  # convert Date vector to yearqtr

Upvotes: 0

micstr
micstr

Reputation: 5206

Old answer but to those arriving here, lubridate has a function %m+%that adds months and preserves monthends.

a <- as.Date("2006-01-01")

Add future months worth of dates:

The original poster wanted 4 quarters in future so that will be 12 months.

future_date <- a %m+% months(12)

future_date 
[1] "2007-01-01"

You could also do years as the period:

future_date <- a %m+% years(1)

Remove months from date:

Subtract dates with %m-%

If you wanted a date 3 months ago from 1/1/2006:

past_date <- a %m-% months(3)

past_date
[1] "2005-10-01"

Example with dates not at end of months:

mplus will preserve days in month:

as.Date("2022-10-10") %m-% months(3)
[1] "2022-07-10"

For more, see documentation on "Add and subtract months to a date without exceeding the last day of the new month"

Upvotes: 1

Kyle Jones
Kyle Jones

Reputation: 11

Lubridate has a function for quarters already included. This is a much better solution than creating your own function.

https://www.rdocumentation.org/packages/lubridate/versions/1.7.4/topics/quarter

Upvotes: 1

Gregor Thomas
Gregor Thomas

Reputation: 145785

The problem is that quarters have different lengths. Q1 is shortest because it includes February (though it ties with Q2 in leap years). Things like this make "adding a quarter to a date" poorly defined. Even adding months to a date can be tricky at the ends months - what is 1 month after January 31?

Beginnings of months are more straightforward, and I would recommend you use the 1st day of quarters rather than the last (if you must use a specific date). lubridate provides functions like floor_date() and ceiling_date() to which you can pass unit = "quarter" and they will return the first day of the current or subsequent quarter, respectively. You can also always add months(3) to a day at the beginning of a month, though of course if your intention is to add 4 quarters you may as well just add 1 year.

Upvotes: 2

RoyalTS
RoyalTS

Reputation: 10203

Just add 12 months or a year instead?

Or if it must be quarters, define yourself a function, like so:

quarters <- function(x) {
   months(3*x)
}

and then use it to add to the date sequence:

date_range <- seq.Date(a, b, by = "quarter")
date_range + quarters(4)

Upvotes: 1

Related Questions