Hello, I have two date strings, say "1972-06-30" and "2012-01-31", and I'd like to get every quarter period end date between those dates? Does anyone know how to do this? Speed is important... Here is a small sample: Two dates: "2007-01-31" "2012-01-31" And I'd like to get this: [1] "2007-03-31" "2007-06-30" "2007-09-30" "2007-12-31" "2008-03-31" "2008-06-30" "2008-09-30" "2008-12-31" [9] "2009-03-31" "2009-06-30" "2009-09-30" "2009-12-31" "2010-03-31" "2010-06-30" "2010-09-30" "2010-12-31" [17] "2011-03-31" "2011-06-30" "2011-09-30" "2011-12-31" Thanks! ben [[alternative HTML version deleted]]
On Apr 18, 2012, at 11:58 AM, Ben quant wrote:> Hello, > > I have two date strings, say "1972-06-30" and "2012-01-31", and I'd like to > get every quarter period end date between those dates? Does anyone know how > to do this? Speed is important... > > Here is a small sample: > > Two dates: > "2007-01-31" > > "2012-01-31" > > And I'd like to get this: > > [1] "2007-03-31" "2007-06-30" "2007-09-30" "2007-12-31" "2008-03-31" > "2008-06-30" "2008-09-30" "2008-12-31" > [9] "2009-03-31" "2009-06-30" "2009-09-30" "2009-12-31" "2010-03-31" > "2010-06-30" "2010-09-30" "2010-12-31" > [17] "2011-03-31" "2011-06-30" "2011-09-30" "2011-12-31" > > > Thanks! > > benFirst thing that comes to mind is to use cut.Date() with breaks = "quarters" and subtract a day, since it will give you the first day of each quarter by default. See ?cut.Date. It returns a grouped sequence based upon the 'breaks' interval, much like ?cut for a continuous variable, with the factor levels being the grouped values. In this case, the first day of each quarter, which I coerce back to Dates. I remove the first value from the result vector and subtract a day. Thus, encapsulating it in a function: Qtrs <- function(Start, End) { Vec <- as.Date(levels(cut(seq.Date(Start, End, by = "month"), breaks = "quarter"))) Vec[-1] - 1 }> Qtrs(as.Date("2007-01-31"), as.Date("2012-01-31"))[1] "2007-03-31" "2007-06-30" "2007-09-30" "2007-12-31" "2008-03-31" [6] "2008-06-30" "2008-09-30" "2008-12-31" "2009-03-31" "2009-06-30" [11] "2009-09-30" "2009-12-31" "2010-03-31" "2010-06-30" "2010-09-30" [16] "2010-12-31" "2011-03-31" "2011-06-30" "2011-09-30" "2011-12-31" Not fully tested, but seems to work, at least with your example dates. Regards, Marc Schwartz
On Wed, Apr 18, 2012 at 12:58 PM, Ben quant <ccquant at gmail.com> wrote:> Hello, > > I have two date strings, say "1972-06-30" and "2012-01-31", and I'd like to > get every quarter period end date between those dates? Does anyone know how > to do this? Speed is important... > > Here is a small sample: > > Two dates: > "2007-01-31" > > "2012-01-31" > > And I'd like to get this: > > [1] "2007-03-31" "2007-06-30" "2007-09-30" "2007-12-31" "2008-03-31" > "2008-06-30" "2008-09-30" "2008-12-31" > ?[9] "2009-03-31" "2009-06-30" "2009-09-30" "2009-12-31" "2010-03-31" > "2010-06-30" "2010-09-30" "2010-12-31" > [17] "2011-03-31" "2011-06-30" "2011-09-30" "2011-12-31"The "yearqtr" class in zoo represents quarters directly 1a. This solution calculates d which is all the days between the two dates inclusive. It then calculates dq which are the unique end of quarters corresponding to those dates. Finally it keeps only the end of quarters between the dates. We know all the end of quarters must be at least as large as the first date so keeping the right end of quarters only involves comparing them to the last date. The approach is rather brute force-ish but does have the advantage of not requiring any date arithmetic and is relatively straight-forward in concept: library(zoo) d <- seq(as.Date("2007-01-31"), as.Date("2012-01-31"), "day") dq <- as.Date(unique(as.yearqtr(d)), frac = 1) dq[dq <= max(d)] 1b. You might also consider whether it would actually be better to represent your quarter ends as yearqtr objects instead. That could be done with this variation: d <- seq(as.Date("2007-01-31"), as.Date("2012-01-31"), "day") qq <- unique(as.yearqtr(d)) qq[as.Date(qq, frac = 1) <= max(d)] 2a. This is a variation of David's solution returning a vector of yearqtr class vector: seq(as.yearqtr(as.Date("2007-01-31")), as.yearqtr(as.Date("2012-01-31")+1)-1/4, 1/4) 2b. or to return a Date class vector: as.Date(seq(as.yearqtr(as.Date("2007-01-31")), as.yearqtr(as.Date("2012-01-31")+1)-1/4, 1/4), frac = 1) -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com