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

Gabor Grothendieck ggrothendieck at gmail.com
Fri Sep 12 04:39:13 CEST 2008


On Thu, Sep 11, 2008 at 10:22 PM, hadley wickham <h.wickham at gmail.com> wrote:
>>> 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")
>
> Thanks for that hint:
>
> floor.Date <- function(date, time) {
>  as.Date(cut(date, time))
> }
>
> ceiling.Date <- function(date, time) {
>  parts <- strsplit(time, " ")[[1]]
>  if (length(parts) == 1) {
>    mult <- 1
>    unit <- time
>  } else {
>    mult <- as.numeric(parts[[1]])
>    unit <- parts[[2]]
>  }
>  unit <- gsub("s$", "", unit)
>
>  up <- c("day" = 1, "week" = 7, "month" = 31, "year" = 365)
>  date <- date + mult * up[unit]
>
>  floor.Date(date, time)
> }
>
> which does what I want, I think - accepting all unit specifications
> that seq.Date and cut.Date do.  I guess I'll just include these
> functions in ggplot2, even though it seems like there should be a more
> suitable home for them.
>
>>> 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)
>
> I think you miss the point that this is for ggplot2, so that using
> plotting primitives from other packages is rather beside the point.
>
>> 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.
>
> That's exactly what I'm arguing - I feel like your argument is the
> equivalent to saying that we don't need floor and ceiling for numbers
> because we have cut.
>
> Hadley
>
> --
> http://had.co.nz/
>

The problem is trying to force everything into Date class.  If you really
want a monthly series you probably want yearmon rather than Date
class and if you want to convert back then as.Date.yearmon
has a frac argument which gives the lowest possible date in the month
if frac = 0 and the highest possible if frac = 1 and an intermediate
value for other values of frac.  Since R is OO its not that hard to
define a variety of classes and have the as functions do the work.

I was not arguing for or against floor or ceiling since that was not the
subject of discussion but simply responding to
the assertions that cut.Date, as.yearmon, etc could not or should
not be used together to get many different desired effects whereas
in fact a one or two line idiom involving them can do everything asked for
and more without having to remember a slew of special purpose
functions.



More information about the R-help mailing list