J'ai des problèmes pour comprendre pourquoi la gestion des dates, des étiquettes et des pauses ne fonctionne pas comme je m'y attendais dans R lorsque j'essayais de faire un histogramme avec ggplot2.
Je recherche:
%Y-b
J'ai téléchargé mes données sur Pastebin pour rendre cela reproductible. J'ai créé plusieurs colonnes car je n'étais pas sûr de la meilleure façon de procéder:
> dates <- read.csv("http://Pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
> 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
Voici ce que j'ai essayé:
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))
Ce qui donne ce graphique . Cependant, je voulais un formatage %Y-%b
, J'ai donc cherché et essayé les éléments suivants, en fonction de ce 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.
Cela me donne ce graphique
J'ai travaillé sur l'exemple dans la documentation ggplot2 dans la section scale_x_date
Et geom_line()
semble casser, étiqueter et centrer correctement les ticks lorsque je l'utilise avec mon même données de l'axe des x. Je ne comprends pas pourquoi l'histogramme est différent.
J'ai d'abord pensé que la réponse de Gauden m'a aidé à résoudre mon problème, mais je suis maintenant perplexe après avoir regardé de plus près. Notez les différences entre les graphiques résultants des deux réponses après le code.
Supposons pour les deux:
library(ggplot2)
library(scales)
dates <- read.csv("http://Pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
Sur la base de la réponse de @ edgester ci-dessous, j'ai pu faire ce qui suit:
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))
Voici ma tentative basée sur la réponse 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))
Graphique basé sur l'approche d'edgester:
Graphique basé sur l'approche de Gauden:
Notez les points suivants:
table(dates$Date)
révèle qu'il y a 19 instances de 2009-12-01
et 26 instances de 2010-03-01
dans les donnéesDes réflexions sur les différences ici? méthode d'edgester pour créer un décompte séparé
En passant, voici d'autres emplacements qui contiennent des informations sur les dates et ggplot2 pour les passants à la recherche d'aide:
format=
Ne fonctionnait pas pour moi.Date
comme continu et je ne pense pas que cela fonctionne si bien. Il on aurait dit qu'il recouvrait le même texte d'étiquette encore et encore, donc les lettres semblaient un peu bizarres. La distribution est en quelque sorte correcte mais il y a des pauses bizarres. Ma tentative basée sur la réponse acceptée était comme ça ( résultat ici ).MISE À JOUR
Je mets à jour l'exemple pour démontrer l'alignement des étiquettes et la définition de limites sur le tracé. Je démontre également que as.Date
fonctionne en effet lorsqu'il est utilisé de manière cohérente (en fait, il est probablement mieux adapté à vos données que mon exemple précédent).
Et voici (un peu excessivement) du code commenté:
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
J'essaie une solution qui fait tout dans ggplot2
, dessinant sans agrégation, et fixant les limites sur l'axe des x entre le début de 2009 et la fin de 2011.
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
Bien sûr, cela pourrait faire avec le jeu avec les options d'étiquette sur l'axe, mais c'est pour compléter le tracé avec une routine courte et propre dans le package de traçage.
Je pense que l'élément clé est que vous devez faire le calcul de fréquence en dehors de ggplot. Utilisez agrégat () avec geom_bar (stat = "identité") pour obtenir un histogramme sans les facteurs réorganisés. Voici un exemple de code:
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)
Le graphique d'erreur sous le titre "Graphique basé sur l'approche de Gauden" est dû au paramètre binwidth: ... + Geom_histogram (binwidth = 30, color = "white") + ... Si nous changeons la valeur de 30 en un valeur inférieure à 20, comme 10, vous obtiendrez toutes les fréquences.
En statistiques les valeurs sont plus importantes que la présentation est plus importante un graphique fade à une très jolie image mais avec des erreurs.