[R] Truncating dates (and other date-time manipulations)

Gabor Grothendieck ggrothendieck at gmail.com
Fri Sep 12 03:46:14 CEST 2008


On Thu, Sep 11, 2008 at 5:42 PM, hadley wickham <h.wickham at gmail.com> wrote:
> On Thu, Sep 11, 2008 at 11:00 AM, Gabor Grothendieck
> <ggrothendieck at gmail.com> wrote:
>> See ?cut.Date
>>
>> In the zoo package see:
>> ?as.yearmon
>> ?as.yearqtr
>> ?aggregate.zoo
>>
>> and the many examples in:
>> ?plot.zoo
>> ?xyplot.zoo
>> as well as the three zoo vignettes.
>>
>> Also in the xts package look at
>> ?to.period
>>
>> For regularly spaced series the tis package supports a wide
>> variety of time bases and can convert among them.
>>
>> There are as.zoo.tis and as.tis.zoo routines in zoo and tis; also,
>> xts is a subclass of zoo so all these packages can work together.
>
> Ok, lets take a concrete example:
>
> dates <- structure(c(8516, 8544, 8568, 8596, 8609, 8666, 8701, 8750, 8754,
> 8798, 8811, 8817, 8860, 8873, 8918, 8931, 8966, 9020, 9034, 9056
> ), class = "Date")
>
>> range(dates)
> [1] "1993-04-26" "1994-10-18"
>
> I want to be able to say: give me a monthly time series that spans
> this range - i.e. it should start on 1993-04-01 and continue to
> 1994-11-01.  I should equally easily be able to say give me a yearly
> time series, or every 2 months or every 3 months, or 2 weeks etc.
>
> I don't think that cut.Date helps because I want to make a new series,
> not divide up an existing one, similarly with to.period.  as.yearmon,

Use cut.Date like this (assuming the dates variable as in your post):

r <- as.Date(cut(range(dates), "month"))

# every month
seq(r[1], r[2]+32, "month")

# every 2nd month
seq(r[1], r[2]+32, "2 month")

# every 3rd month
seq(r[1], r[2]+32, "3 month")

# every 2nd week
seq(r[1], as.Date(cut(r[2]+32, "month")), "2 week")

or with yearmon:

rr <- as.yearmon(r)
as.yearmon(seq(rr[1], rr[2]+1/12, 1/12))
as.yearmon(seq(rr[1], rr[2]+1/12, 2/12))
as.yearmon(seq(rr[1], rr[2]+1/12, 3/12))

# or if you want the final answer as Date class
as.Date(as.yearmon(seq(rr[1], rr[2]+1/12, 1/12)))
# etc

> as.yearqtr etc, might be helpful but I'd need to stitch them together
> myself and they don't return dates so I'd have to convert back for
> plotting.   plot.zoo doesn't help because all the examples are regular

Also both yearmon and yearqtr can be used for plotting -- you don't
have to convert them back to Dates just for plotting as zoo provides
axis.yearmon and axis.yearqtr and furthermore there is no assumption
of regular series needed.

plot(as.yearmon(Sys.Date()) + c(0, 5, 7, 20)/12, 1:4)

Although in all these examples you do have to combine several functions,
if there were a function for every conceivable date manipulation there
would be too large a number to remember and its better to have a good
set of primitives that are sufficiently powerful that most operations can
be done in one or two lines as shown above.



More information about the R-help mailing list