Comprender las fechas y trazar un histogtwig con ggplot2 en R

Pregunta principal

Tengo problemas para comprender por qué el manejo de fechas, tags y pausas no funciona como esperaba en R cuando bash hacer un histogtwig con ggplot2.

Estoy buscando:

  • Un histogtwig de la frecuencia de mis fechas
  • Marcas marcadas bajo las barras correspondientes
  • Etiquetas de fecha en formato %Yb
  • Límites apropiados; espacio mínimo minimizado entre el borde del espacio de la grilla y las barras más externas

He subido mis datos a pastebin para hacer esto reproducible. Creé varias columnas porque no estaba seguro de la mejor manera de hacerlo:

 > dates  head(dates) YM Date Year Month 1 2008-Apr 2008-04-01 2008 4 2 2009-Apr 2009-04-01 2009 4 3 2009-Apr 2009-04-01 2009 4 4 2009-Apr 2009-04-01 2009 4 5 2009-Apr 2009-04-01 2009 4 6 2009-Apr 2009-04-01 2009 4 

Esto es lo que intenté:

 library(ggplot2) library(scales) dates$converted <- as.Date(dates$Date, format="%Y-%m-%d") ggplot(dates, aes(x=converted)) + geom_histogram() + opts(axis.text.x = theme_text(angle=90)) 

Que produce este gráfico . Yo quería el formato %Y-%b , así que busqué e intenté lo siguiente, basado en este SO :

 ggplot(dates, aes(x=converted)) + geom_histogram() + scale_x_date(labels=date_format("%Y-%b"), + breaks = "1 month") + opts(axis.text.x = theme_text(angle=90)) stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this. 

Eso me da este gráfico

  • Corregir el formato de etiqueta del eje x
  • La distribución de frecuencia ha cambiado de forma (¿problema de ancho de banda?)
  • Las marcas no aparecen centradas debajo de las barras
  • Los xlims también han cambiado

Trabajé a través del ejemplo en la documentación ggplot2 en la sección scale_x_date y geom_line() parece romper, etiquetar y centrar tics correctamente cuando lo uso con mis mismos datos del eje x. No entiendo por qué el histogtwig es diferente.


Actualizaciones basadas en respuestas de edgester y gauden

Inicialmente pensé que la respuesta de Gauden me ayudó a resolver mi problema, pero ahora estoy desconcertado después de mirar más de cerca. Tenga en cuenta las diferencias entre los gráficos resultantes de las dos respuestas después del código.

Asume para ambos:

 library(ggplot2) library(scales) dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T) 

Basado en la respuesta de @deraster a continuación, pude hacer lo siguiente:

 freqs <- aggregate(dates$Date, by=list(dates$Date), FUN=length) freqs$names <- as.Date(freqs$Group.1, format="%Y-%m-%d") ggplot(freqs, aes(x=names, y=x)) + geom_bar(stat="identity") + scale_x_date(breaks="1 month", labels=date_format("%Y-%b"), limits=c(as.Date("2008-04-30"),as.Date("2012-04-01"))) + ylab("Frequency") + xlab("Year and Month") + theme_bw() + opts(axis.text.x = theme_text(angle=90)) 

Aquí está mi bash basado en la respuesta de Gauden:

 dates$Date <- as.Date(dates$Date) ggplot(dates, aes(x=Date)) + geom_histogram(binwidth=30, colour="white") + scale_x_date(labels = date_format("%Y-%b"), breaks = seq(min(dates$Date)-5, max(dates$Date)+5, 30), limits = c(as.Date("2008-05-01"), as.Date("2012-04-01"))) + ylab("Frequency") + xlab("Year and Month") + theme_bw() + opts(axis.text.x = theme_text(angle=90)) 

Parcela basada en el enfoque de edgeter:

plotter de bordes

Parcela basada en el enfoque de Gauden:

gauden-plot

Tenga en cuenta lo siguiente:

  • lagunas en la ttwig de Gauden para 2009-Dic y 2010-Mar; table(dates$Date) revela que hay 19 instancias de 2009-12-01 y 26 instancias de 2010-03-01 en los datos
  • La ttwig de edgeter comienza en 2008-abr y termina en 2012-mayo. Esto es correcto en base a un valor mínimo en los datos de 2008-04-01 y una fecha máxima de 2012-05-01. Por alguna razón, la ttwig de Gauden comienza en 2008-Mar y aún de alguna manera se las arregla para finalizar en 2012-mayo. Después de contar los contenedores y leer a lo largo de las tags de los meses, durante mi vida no puedo entender qué ttwig tiene un extra o si falta un contenedor del histogtwig.

¿Alguna idea sobre las diferencias aquí? El método de edgeter para crear un conteo separado


Referencias relacionadas

Como un aparte, aquí hay otras ubicaciones que tienen información sobre las fechas y ggplot2 para los transeúntes en busca de ayuda:

  • Empezó aquí en learnr.wordpress, un popular blog de R. Decía que necesitaba obtener mis datos en formato POSIXct, que ahora creo que es falso y que desperdicia mi tiempo.
  • Otra publicación de aprendizaje recrea una serie temporal en ggplot2, pero no era realmente aplicable a mi situación.
  • r-bloggers tiene una publicación sobre esto , pero parece desactualizada. La sencilla format= opción no funcionó para mí.
  • Esta pregunta SO está jugando con breaks y tags. Intenté tratar mi vector Date como continuo y no creo que funcionó tan bien. Parecía que estaba superponiendo el mismo texto de etiqueta una y otra vez, por lo que las letras parecían algo extrañas. La distribución es más o menos correcta, pero hay pausas extrañas. Mi bash basado en la respuesta aceptada fue así ( resultado aquí ).

ACTUALIZAR

Versión 2: Uso de la clase Date

Actualizo el ejemplo para demostrar la alineación de las tags y el establecimiento de límites en la ttwig. También demuestro que, como as.Date , de hecho funciona cuando se usa de manera consistente (de hecho, es probable que sea una mejor opción para sus datos que mi ejemplo anterior).

The Target Plot v2

histograma basado en fecha

El código v2

Y aquí está (algo excesivamente) código comentado:

 library("ggplot2") library("scales") dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T) dates$Date <- as.Date(dates$Date) # convert the Date to its numeric equivalent # Note that Dates are stored as number of days internally, # hence it is easy to convert back and forth mentally dates$num <- as.numeric(dates$Date) bin <- 60 # used for aggregating the data and aligning the labels p <- ggplot(dates, aes(num, ..count..)) p <- p + geom_histogram(binwidth = bin, colour="white") # The numeric data is treated as a date, # breaks are set to an interval equal to the binwidth, # and a set of labels is generated and adjusted in order to align with bars p <- p + scale_x_date(breaks = seq(min(dates$num)-20, # change -20 term to taste max(dates$num), bin), labels = date_format("%Y-%b"), limits = c(as.Date("2009-01-01"), as.Date("2011-12-01"))) # from here, format at ease p <- p + theme_bw() + xlab(NULL) + opts(axis.text.x = theme_text(angle=45, hjust = 1, vjust = 1)) p 

Versión 1: Usando POSIXct

Intento una solución que haga todo en ggplot2 , dibujar sin la agregación y establecer los límites en el eje x entre principios de 2009 y finales de 2011.

The Target Plot v1

trama con límites establecidos en ggplot2

El código v1

 library("ggplot2") library("scales") dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T) dates$Date <- as.POSIXct(dates$Date) p <- ggplot(dates, aes(Date, ..count..)) + geom_histogram() + theme_bw() + xlab(NULL) + scale_x_datetime(breaks = date_breaks("3 months"), labels = date_format("%Y-%b"), limits = c(as.POSIXct("2009-01-01"), as.POSIXct("2011-12-01")) ) p 

Por supuesto, podría hacerlo jugando con las opciones de etiqueta en el eje, pero esto es para redondear el trazado con una rutina breve y clara en el paquete de trazado.

Creo que la clave es que necesitas hacer el cálculo de frecuencia fuera de ggplot. Use aggregate () con geom_bar (stat = “identity”) para obtener un histogtwig sin los factores reordenados. Aquí hay un código de ejemplo:

 require(ggplot2) # scales goes with ggplot and adds the needed scale* functions require(scales) # need the month() function for the extra plot require(lubridate) # original data #df<-read.csv("http://pastebin.com/download.php?i=sDzXKFxJ", header=TRUE) # simulated data years=sample(seq(2008,2012),681,replace=TRUE,prob=c(0.0176211453744493,0.302496328928047,0.323054331864905,0.237885462555066,0.118942731277533)) months=sample(seq(1,12),681,replace=TRUE) my.dates=as.Date(paste(years,months,01,sep="-")) df=data.frame(YM=strftime(my.dates, format="%Y-%b"),Date=my.dates,Year=years,Month=months) # end simulated data creation # sort the list just to make it pretty. It makes no difference in the final results df=df[do.call(order, df[c("Date")]), ] # add a dummy column for clarity in processing df$Count=1 # compute the frequencies ourselves freqs=aggregate(Count ~ Year + Month, data=df, FUN=length) # rebuild the Date column so that ggplot works freqs$Date=as.Date(paste(freqs$Year,freqs$Month,"01",sep="-")) # I set the breaks for 2 months to reduce clutter g<-ggplot(data=freqs,aes(x=Date,y=Count))+ geom_bar(stat="identity") + scale_x_date(labels=date_format("%Y-%b"),breaks="2 months") + theme_bw() + opts(axis.text.x = theme_text(angle=90)) print(g) # don't overwrite the previous graph dev.new() # just for grins, here is a faceted view by year # Add the Month.name factor to have things work. month() keeps the factor levels in order freqs$Month.name=month(freqs$Date,label=TRUE, abbr=TRUE) g2<-ggplot(data=freqs,aes(x=Month.name,y=Count))+ geom_bar(stat="identity") + facet_grid(Year~.) + theme_bw() print(g2) 

El gráfico de error con el título “Gráfico basado en el enfoque de Gauden” se debe al parámetro binwidth: … + Geom_histogram (binwidth = 30, color = “white”) + … Si cambiamos el valor de 30 a a valor inferior a 20, como 10, obtendrá todas las frecuencias.

En estadística los valores son más importantes que la presentación; es más importante un gráfico insulso a una imagen muy bonita pero con errores.