2012-09-12 17 views
5

Sto cercando di ottenere ggplot per produrre un istogramma con i raccoglitori che sono 3 mesi di larghezza. Non 90 giorni ma 3 mesi. In termini di giorni, questo è un binning di larghezza disuguale. Si noti che i segni di graduazione a intervalli di 3 mesi funzionano correttamente. È la larghezza del cestino con cui sto avendo problemi. C'è stato un bel po 'di discussione qui, ma non sono riuscito a trovare una soluzione.histgramming date con i disuguali in ggplot

Understanding dates and plotting a histogram with ggplot2 in R

Ecco una dichiarazione del problema. Nota che potrei ovviamente aggregare i risultati al di fuori di ggplot e quindi tracciarli, magari come fattori in ggplot. Ma stavo cercando una soluzione ggplot.

set.seed(seed=1) 
dts<-as.Date('2012-01-01') + round(365*rnorm(500)) 
dts<-data.frame(d=dts) 
g<-ggplot(dts,aes(x=d, y=..count..)) 

#this isnt what I want. It is 90 days, not 3 months. 
#Setting binwidth=' 3 months' also doesnt work 
g + geom_histogram(fill='blue',binwidth=90) + 
    scale_x_date(breaks = date_breaks('3 months'), #seq(as.Date('2008-1-1'), as.Date('2012-3-1'), '3 month'), 
       labels = date_format("%Y-%m"), 
       limits = c(as.Date('2010-1-1'), as.Date('2014-1-1'))) + 
    opts(axis.text.x = theme_text(angle=90)) 

#this doesnt work either. 
#get: stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this. 
#  Error in `+.Date`(left, right) : binary + is not defined for Date objects 
g + geom_bar(fill='blue') + 
    stat_bin(breaks=seq(as.Date('2010-1-1'), as.Date('2014-1-1'), '3 month')) + 
    scale_x_date(breaks = date_breaks('3 months'), #seq(as.Date('2008-1-1'), as.Date('2012-3-1'), '3 month'), 
       labels = date_format("%Y-%m"), 
       limits = c(as.Date('2010-1-1'), as.Date('2014-1-1'))) + 
    opts(axis.text.x = theme_text(angle=90)) 

Forse la risposta è: ggplot non creerà bidoni di 3 mesi di larghezza (o N di mese).

+2

Penso che dovresti fare l'aggregazione al di fuori di 'ggplot' ... il consenso degli esperti (ad esempio sulla mailing list ggplot) sembra essere che una volta che le cose si complicano sufficientemente, è meglio fare l'aggregazione e poi alimentare i risultati in 'ggplot' (con le opportune' geom's, puoi fare in modo che i risultati appaiano esattamente come 'ggplot' * avrebbe * tracciato loro se fosse in grado di eseguire larghezze bin non uguali) invece di fare backflip per farlo all'interno di 'ggplot' (che in fin dei conti è principalmente un pacchetto * di plotting *). –

+0

Perché i tuoi limiti sono così lontani dalle tue pause ??? –

+0

Grazie Ben per la guida. DWin: Non capisco perché i limiti non siano rigorosamente applicati e perché, quindi, ci sia qualche strapiombo e ciò che appare visivamente sia un bidone a metà larghezza su ciascuna estremità. Forse è legato ai miei limiti e le etichette sono di 3 mesi ma la larghezza di banda è di 90 giorni. –

risposta

3

Come notato, stat_bin consentirà la specifica dei bordi del raccoglitore. Ma quando si lavora con le date, è spesso il caso che il valore debba essere trasformato manualmente nella scala interna per funzionare. Inoltre, nel tuo secondo esempio, hai sia un geom_bar sia un stat_bin che sta tracciando due livelli diversi. Ecco una versione funzionante:

g + stat_bin(breaks=as.numeric(seq(as.Date('2010-1-1'), 
            as.Date('2014-1-1'), '3 month')), 
      fill = "blue", 
      position = "identity") + 
    scale_x_date(breaks = date_breaks('3 months'), 
       labels = date_format("%Y-%m"), 
       limits = c(as.Date('2010-1-1'), as.Date('2014-1-1'))) + 
    opts(axis.text.x = theme_text(angle=90)) 

Nota che ho avvolto l'argomento breaks-stat_bin in as.numeric. Inoltre, ho aggiunto un argomento position="identity" a stat_bin per eliminare l'avviso relativo alle larghezze bin non uguali (poiché esiste un solo gruppo, non è necessario che sia impilato con nulla).