Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using seq.Date as breaks in stat_bin for time-series

Tags:

r

ggplot2

I am attempting to bin time-series data from several years of observation by month using the stat_bin function in ggplot2. The code looks like this:

month.breaks<-seq.Date(from=min(afg$DateOccurred),to=max(afg$DateOccurred),by="month")  # All months, for breaks
report.region<-ggplot(afg,aes(x=DateOccurred))+stat_bin(aes(y=..density..,fill=Type),breaks=month.breaks)+facet_wrap(~Region)
print(report.region)

When I run print, however, I get the following error:

Error in `+.Date`(left, right) : binary + is not defined for Date objects

If I am reading this correctly, the plus operator is not defined for Date objects and thus it is not possible to perform this type of binning?

like image 332
DrewConway Avatar asked Jul 27 '10 03:07

DrewConway


3 Answers

When I've gotten that error from ggplot2 in other circumstances, I've been able to get away with using as.numeric() around the sequence I'm using for breaks. For example,

library(lubridate)
library(ggplot2)
library(scales)

somedates <- ymd(20130101) + ddays(runif(100, 0, 364)) #generate some fake event dates
somedatesformatted <- data.frame(Dates=as.Date(somedates)) #format them as data ggplot likes
monthbins <- as.numeric(seq(as.Date('2013-01-01'), as.Date('2014-01-01'), '1 month')) # generate breaks for binning event dates and wrap in as.numeric()

ggplot(somedatesformatted, aes(x=Dates)) + 
    stat_bin(breaks=monthbins) +
    ylab("Events per Month") +
    ylim(c(0,30)) +
    scale_x_date(breaks = '1 month',
             labels = date_format("%b"),
             limits = c(as.Date('2013-01-01'), as.Date('2013-12-31')))
like image 157
sus Avatar answered Nov 19 '22 01:11

sus


I can reproduce your error as follows:

> break.dates <- seq.Date(from=as.Date('2001-01-01'),
                          to=as.Date('2001-04-01'),
                          by="month") 
> break.dates
[1] "2001-01-01" "2001-02-01" "2001-03-01" "2001-04-01"
## add an offset, which increases the dates by a day
> break.dates + 1
[1] "2001-01-02" "2001-02-02" "2001-03-02" "2001-04-02"
## try to add two date objects together - this does not make sense!
> break.dates + break.dates
Error in `+.Date`(break.dates, break.dates) :
  binary + is not defined for Date objects

It does not make sense to add two dates together, since there is no natural "zero" on the date scale. However the + operator is defined for Date objects in situations where it makes sense.

like image 38
nullglob Avatar answered Nov 19 '22 00:11

nullglob


It seems to me you can get the same result if you just transform the data first, then pass it to the plot method.

For instance (time series data in months binned by year):

data(AirPassengers)   # time series in months (supplied w/ default R install)
AP = AirPassengers
library(xts)
X = as.xts(AP)      # need xts object to pass to xts binning method
ndx = endpoints(X, on="years")    # binning method requires indices for desired bin freq
X_yr = period.apply(x=X, INDEX=ndx, FUN=sum)   # X_yr is the binned data
like image 1
doug Avatar answered Nov 19 '22 01:11

doug