Question principale
Je rencontre des problèmes pour comprendre pourquoi la gestion des dates, des libellés et des interruptions ne fonctionne pas comme je l'aurais attendu dans R lorsque j'essaie de faire un histogramme avec ggplot2.
Je recherche :
- Un histogramme de la fréquence de mes dates
- Des repères centrés sous les barres correspondantes
- Des libellés de date au format
%Y-b
- Des limites appropriées ; espace vide minimisé entre le bord de l'espace de la grille et les barres les plus extérieures
J'ai mis mes données en ligne sur pastebin pour que vous puissiez reproduire ceci. J'ai créé plusieurs colonnes car je n'étais pas sûr de la meilleure façon de le faire :
> 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))
Cela donne ce graphique. Je voulais un format %Y-%b
, donc j'ai cherché autour et essayé ce qui suit, basé sur 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
- Format correct de l'axe x
- La distribution de fréquence a changé de forme (problème de binwidth?)
- Les repères ne semblent pas centrés sous les barres
- Les limites ont également changé
J'ai travaillé sur l'exemple dans la documentation de ggplot2 dans la section scale_x_date
et geom_line()
semble casser, libeller et centrer correctement les repères quand je l'utilise avec les mêmes données sur l'axe x. Je ne comprends pas pourquoi l'histogramme est différent.
Mises à jour basées sur les réponses d'edgester et gauden
Je pensais initialement que la réponse de gauden m'avait aidé à résoudre mon problème, mais je suis maintenant perplexe après avoir examiné de plus près. Notez les différences entre les graphiques résultants des deux réponses après le code.
Supposez pour les deux :
library(ggplot2)
library(scales)
dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
D'après 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("Fréquence") + xlab("Année et mois") +
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("Fréquence") + xlab("Année et mois") +
theme_bw() + opts(axis.text.x = theme_text(angle=90))
Graphique basé sur l'approche de edgester :
Graphique basé sur l'approche de gauden :
Remarquez ce qui suit :
- des lacunes dans le graphique de gauden pour 2009-Dec et 2010-Mar;
table(dates$Date)
révèle qu'il y a 19 instances de2009-12-01
et 26 instances de2010-03-01
dans les données - le graphique de edgester commence en avril 2008 et se termine en mai 2012. C'est correct en fonction d'une valeur minimale dans les données du 1er avril 2008 et d'une date maximale du 1er mai 2012. Pour une raison quelconque, le graphique de gauden commence en mars 2008 et se termine toujours en mai 2012. Après avoir compté les bacs et lu le long des libellés des mois, je ne peux vraiment pas comprendre quel graphique a un excès ou manque un bac de l'histogramme!
Des idées sur les différences ici ? la méthode de edgester pour créer un comptage séparé
Références connexes
À titre de remarque, voici d'autres sources d'informations sur les dates et ggplot2 pour les passants à la recherche d'aide :
- Commencé ici sur learnr.wordpress, un blog R populaire. Il indiquait que je devais obtenir mes données au format POSIXct, ce que je pense maintenant est faux et a gaspillé mon temps.
- Un autre article de learnr recrée une série temporelle dans ggplot2, mais n'était pas vraiment applicable à ma situation.
- r-bloggers a un article sur ceci, mais il semble obsolète. L'option simple
format=
n'a pas fonctionné pour moi. - Cette question SO joue avec les interruptions et les libellés. J'ai essayé de traiter mon vecteur
Date
comme continu et je ne pense pas que cela a très bien fonctionné. On dirait qu'il superposait le même texte de libellé encore et encore donc les lettres avaient l'air un peu étranges. La distribution est assez correcte mais il y a des interruptions étranges. Ma tentative basée sur la réponse acceptée était comme ça (résultat ici).
0 votes
Vérifiez le package
lubridate
.0 votes
@gsk3 J'en avais entendu parler, bien que je pense que cela aide avec la mise en forme, les intervalles, l'incrémentation, et ainsi de suite. Penses-tu que mon problème réside dans quelque chose que lubridate pourrait résoudre? Je pensais que c'était lié à la syntaxe d'utilisation correcte de ggplot2.
0 votes
Je ne comprends pas votre question. Avez-vous essayé de poser une question et ensuite d'y répondre dans le même message ? Si c'est le cas, veuillez reformuler votre question en tant que question, puis y répondre vous-même. (Cela est activement encouragé sur SO.)
0 votes
@Andrie: Non. J'ai essayé de présenter les différentes choses que j'ai essayées, que je considère comme un échec, malgré le résultat souhaité. Si vous remarquez, la pièce finale est le résultat d'une astuce brute et stupide. J'ai littéralement dû regarder l'ordre existant des 48 niveaux de
dates$Date
et faire quelque chose commedlevels = factor(dates$Date,levels(dates$Date)[c(5,4,1,7,16,14,12,18...34,45,23,48)])
pour les obtenir dans le bon ordre. Je suis sûr qu'il y a une meilleure solution que cela. J'espère que cela clarifie les choses?1 votes
Veuillez poser une nouvelle question, car vous venez de changer votre ensemble de données d'origine. Cette question est très confuse à lire. Veuillez accepter une réponse et voter pour toutes les réponses qui étaient utiles.
0 votes
@edgester: Je n'ai pas changé mon jeu de données. Pourquoi dis-tu ça? J'ai ajusté le bit de lecture du fichier CSV pour pointer directement vers pastebin au lieu du code que j'avais, c'est ainsi que je lis le fichier localement. J'ai voté positivement et j'accepterai une question quand j'aurai le temps de m'assurer que cela fonctionne et est la meilleure réponse à cette question.
1 votes
@edgester: Je pourrais réécrire la question. C'était difficile de la garder concise. Le problème est que ggplot2 est confus avec les dates/heure. Je voulais illustrer combien il y a de façons théoriques d'essayer de faire fonctionner cela et les problèmes avec chacune.
0 votes
Dans update2, vous définissez aes(x=Date..) au lieu de aes(x=Dates...). La colonne Date est un facteur. Dates est de type date. Ajoutez '''dates <- subset(dates, Dates >= as.Date("2009-01-01") & Dates <= as.Date("2011-12-01"))''' Avant de représenter graphiquement ou de réduire votre jeu de données à la plage désirée.
0 votes
@edgester: Bien vu. C'était une faute de frappe :( Je l'ai exécuté comme la réponse de gauden ci-dessous, qui a simplement remplacé
dates$Date
par une versionas.Date()
de lui-même. Désolé pour la confusion. Je suis d'accord que cela est devenu long et difficile à suivre. J'ai l'intention de le rendre plus présentable pour la postérité.0 votes
Voir aussi stackoverflow.com/questions/2409317/…