2012-09-12 10 views
5

Estoy tratando de obtener ggplot para producir un histograma con contenedores que tienen 3 meses de ancho. No 90 días sino 3 meses. En términos de días, este es un binning de ancho desigual. Tenga en cuenta que las marcas a intervalos de 3 meses funcionan bien. Es el ancho del contenedor con el que estoy teniendo problemas. Hubo bastante discusión aquí pero no pude encontrar una resolución.fechas de histgramas con contenedores desiguales en ggplot

Understanding dates and plotting a histogram with ggplot2 in R

Aquí es una declaración del problema. Tenga en cuenta que obviamente podría agregar los resultados fuera de ggplot y luego trazarlos, tal vez como factores en ggplot. Pero estaba buscando una solución ggplot completa.

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)) 

Quizás la respuesta es: ggplot no creará depósitos de 3 meses de ancho (o N mes de ancho).

+2

Creo que deberías hacer la agregación fuera de 'ggplot' ... el consenso de los expertos (por ejemplo, en la lista de distribución de ggplot) parece ser que una vez que las cosas se complican lo suficiente, es mejor hacer la agregación y luego alimentar los resultados en 'ggplot' (con' geom's apropiado, puedes hacer que los resultados se vean exactamente de la misma manera en que 'ggplot' * los habría dibujado si fuera capaz de hacer anchos de bin desiguales) en lugar de hacer backflips para hacerlo dentro de 'ggplot' (que después de todo es principalmente un paquete * plotting *). –

+0

¿Por qué sus límites están tan desfasados ​​de sus descansos? –

+0

Gracias a Ben por la guía. DWin: No entiendo por qué los límites no se aplican estrictamente y por qué, por lo tanto, hay algo sobresaliente y lo que parece ser visualmente un cubo de medio ancho en cada extremo. Quizás esté relacionado con mis límites y mis etiquetas, que son de 3 meses, pero el ancho de banda es de 90 días. –

Respuesta

3

Como habrás notado, stat_bin permitirá la especificación de los bordes del contenedor. Pero cuando se trabaja con fechas, a menudo el valor se debe transformar en la escala interna manualmente para que funcione. Además, en su segundo ejemplo, tiene un geom_bar y un stat_bin que está trazando dos capas diferentes. Aquí está una versión de trabajo:

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)) 

Tenga en cuenta que me he envuelto el argumento breaks-stat_bin en as.numeric. Además, agregué un argumento position="identity" al stat_bin para eliminar la advertencia sobre el ancho desigual de los contenedores (dado que solo hay un grupo, no necesita apilarse con nada).