Ce que montre un histogramme
Un histogramme répond à une question sur une variable numérique : comment les valeurs sont-elles distribuées ? Il découpe l'étendue des données en intervalles consécutifs (classes), compte combien d'observations tombent dans chacun, et dessine une barre par classe dont la hauteur est cet effectif. Là où les données sont denses, les barres sont hautes ; là où elles sont rares, elles sont courtes.
Cette seule image te dit des choses qu'une moyenne et un écart-type ne peuvent pas dire : si les données ont un pic ou deux, si elles sont symétriques ou étirées vers une queue, et s'il y a des valeurs isolées loin du reste. C'est en général le tout premier graphique à faire quand tu rencontres un nouveau jeu de données, juste à côté des chiffres des statistiques descriptives.
En R la fonction est hist(), et ça tient en une ligne.
Ton premier histogramme avec hist()
Simulons les tailles de 200 personnes - distribuées normalement autour de 170 cm avec un écart-type de 10 (voir les nombres aléatoires pour ce que font set.seed() et rnorm()) :
set.seed(42)
heights <- rnorm(200, mean = 170, sd = 10)
hist(heights)
R choisit les classes lui-même et dessine un empilement de barres en cloche : des barres courtes vers 145 cm, montant à travers les 160, culminant vers 170, et redescendant symétriquement au-delà de 190. L'axe vertical est étiqueté « Frequency » - des effectifs bruts - et le titre et l'étiquette d'axe viennent du nom de la variable.
Les réglages par défaut sont délibérément sobres. Les arguments habituels d'habillage marchent tous ici :
hist(heights,
main = "Distribution of heights",
xlab = "Height (cm)",
col = "steelblue",
border = "white")
col remplit les barres, border colore leurs contours - border = "white" donne l'aspect propre à barres séparées qu'on voit dans la plupart des publications. Tout ce que dit le guide de plot() sur les couleurs et les titres s'applique sans changement.
Largeur des classes : l'argument breaks
L'argument le plus important de hist() est breaks, parce que la largeur des classes décide de l'histoire que raconte le graphique. Mêmes données, deux réglages :
hist(heights, breaks = 5) # five wide bins: a crude, blocky bell
hist(heights, breaks = 30) # thirty narrow bins: detail, plus noise
Avec breaks = 5 l'histogramme est si grossier que tout ressemble à une bosse unique et lisse - un second amas ou un trou dans les données serait invisible. Avec breaks = 30 tu vois la structure fine, mais des oscillations aléatoires commencent à se faire passer pour des caractéristiques. Aucun n'est « correct » ; le geste honnête est d'essayer plusieurs réglages et de voir quelles caractéristiques survivent.
breaks accepte trois formes :
- Un nombre -
breaks = 30- une suggestion du nombre de classes. R l'ajuste pour tomber sur des bornes propres, tu peux donc obtenir 28 ou 33 classes. Ça surprend tout le monde une fois. - Un vecteur de points de coupe -
breaks = seq(140, 200, by = 5)- les bornes exactes des classes, sans négociation. Utilise ça quand les classes doivent s'aligner entre plusieurs histogrammes que tu compares. - Un nom de règle -
breaks = "FD"pour Freedman-Diaconis, qui choisit la largeur d'après la dispersion des données et la taille de l'échantillon, et se comporte bien sur des données asymétriques.
Histogrammes de densité et courbe normale
Par défaut la hauteur des barres est un effectif (freq = TRUE). Mettre freq = FALSE remet les barres à l'échelle pour que leur aire totale vaille 1 - l'échelle de densité. La forme ne change pas ; l'axe vertical, si. L'intérêt, c'est qu'un histogramme de densité vit sur la même échelle qu'une densité de probabilité, tu peux donc superposer une courbe théorique directement sur les données :
hist(heights,
freq = FALSE,
col = "gray90",
main = "Heights vs. a normal curve",
xlab = "Height (cm)")
curve(dnorm(x, mean = mean(heights), sd = sd(heights)),
add = TRUE, col = "tomato", lwd = 2)
curve() avec add = TRUE dessine la courbe en cloche par-dessus l'histogramme existant (le x dans dnorm(x, ...) est un espace réservé que curve() remplit, pas une variable à toi). Si les barres épousent la courbe, un modèle normal est raisonnable ; là où elles s'en écartent - une queue lourde, un second pic - le modèle rate quelque chose. Saute freq = FALSE et la courbe rampera inutilement au bas du graphique, parce qu'effectifs et densités sont sur des échelles différentes.
Les nombres derrière les barres
hist() ne fait pas que dessiner - il renvoie le découpage sous forme de liste. Avec plot = FALSE il saute complètement le dessin et se contente de calculer, ce qui veut dire que tu peux exécuter celui-ci ici même :
h$counts est l'histogramme sous forme de données : chaque nombre est la hauteur d'une barre. La ligne table(cut(...)) en est l'équivalent en mode texte - cut() découpe les valeurs en classes, table() compte chaque classe - et c'est un contrôle de bon sens honnête à afficher avant ou à la place d'un graphique. Si tu affectes sans plot = FALSE (h <- hist(heights)), R dessine et renvoie la liste ; l'affectation ne supprime pas le graphique.
Histogrammes avec ggplot2
La version ggplot2 échange breaks contre binwidth, souvent le bouton le plus naturel - tu dis la largeur d'une classe en unités de données au lieu du nombre de classes que tu veux :
library(ggplot2)
ggplot(data.frame(heights), aes(x = heights)) +
geom_histogram(binwidth = 5, fill = "steelblue", color = "white") +
labs(title = "Distribution of heights", x = "Height (cm)", y = "Count")
binwidth = 5 signifie que chaque barre couvre 5 cm. ggplot2 t'avertit si tu laisses binwidth non défini et retombe discrètement sur 30 classes - écoute l'avertissement, parce que la valeur par défaut est rarement la bonne largeur pour tes données. Pour un coup d'œil rapide sur une variable, hist() demande moins de frappe ; ggplot2 gagne sa place quand l'histogramme a besoin de facettes, de groupes, ou d'un thème cohérent avec le reste de tes figures.
Ce que tu retiens
- Un histogramme montre la distribution d'une variable numérique :
hist(x)et c'est fait. breaksest l'argument qui compte - un nombre n'est qu'une suggestion, un vecteur fixe les bornes exactes,"FD"choisit une largeur défendable. Essaie toujours plus d'un réglage.freq = FALSEbascule sur l'échelle de densité, ce qui permet àcurve(dnorm(...), add = TRUE)de superposer une courbe normale de façon sensée.hist(x, plot = FALSE)renvoie les classes sous forme de données ($breaks,$counts,$mids) ;table(cut(x, breaks))en est l'équivalent purement textuel.- En ggplot2,
geom_histogram(binwidth = ...)- et fixebinwidthtoi-même.
Prochaine étape : la boîte à moustaches - le graphique de distribution qui brille vraiment quand tu compares des groupes côte à côte.
Questions fréquentes
Comment faire un histogramme en R ?
Appelle hist(x) sur un vecteur numérique. R découpe l'étendue de x en classes et dessine une barre par classe, la hauteur de la barre indiquant combien de valeurs tombent dedans. Ajoute breaks = pour contrôler le nombre de classes et col = pour colorer les barres.
Que fait l'argument breaks dans hist() ?
Il contrôle le découpage en classes. Un simple nombre comme breaks = 30 est une suggestion du nombre de classes à utiliser (R arrondit à des bornes propres), un vecteur comme breaks = seq(140, 200, by = 5) fixe les points de coupe exacts, et breaks = "FD" utilise la règle de Freedman-Diaconis.
Comment superposer une courbe normale à un histogramme en R ?
Trace l'histogramme sur l'échelle de densité avec freq = FALSE, puis ajoute la courbe avec curve(dnorm(x, mean = mean(data), sd = sd(data)), add = TRUE). Sur l'échelle des fréquences, la courbe resterait inutilement collée à zéro, donc freq = FALSE est indispensable.
Quelle est la différence entre un histogramme et un diagramme en barres ?
Un histogramme découpe en classes une variable numérique, donc l'axe horizontal est une échelle continue et les barres se touchent. Un diagramme en barres compare des catégories distinctes, donc les barres sont séparées. En R, c'est hist() pour les nombres et barplot() pour les effectifs de catégories.