Menu

Istogramma in R: hist() spiegato con esempi

Come fare un istogramma in R con hist(): scegliere i breaks, dare stile alle barre, passare alla scala di densità, sovrapporre una curva normale e la versione ggplot2.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Cosa mostra un istogramma

Un istogramma risponde a una domanda su una variabile numerica: come sono distribuiti i valori? Divide l'intervallo dei dati in intervalli consecutivi (classi, o bin), conta quante osservazioni cadono in ciascuno e disegna una barra per classe, alta quanto quel conteggio. Dove i dati sono fitti le barre sono alte; dove sono radi, sono basse.

Quell'unica immagine ti dice cose che media e deviazione standard non possono dirti: se i dati hanno uno o due picchi, se sono simmetrici o sbilanciati verso una coda, e se ci sono valori isolati lontani dal resto. Di solito è il primissimo grafico da fare quando incontri un nuovo dataset, insieme ai numeri della statistica descrittiva.

In R la funzione è hist(), e basta una riga.

Il tuo primo istogramma con hist()

Simuliamo l'altezza di 200 persone, con distribuzione normale intorno a 170 cm e deviazione standard 10 (vedi numeri casuali per sapere cosa fanno set.seed() e rnorm()):

set.seed(42)
heights <- rnorm(200, mean = 170, sd = 10)

hist(heights)

R sceglie da solo le classi e disegna una pila di barre a forma di campana: barre basse vicino a 145 cm, che crescono lungo i 160, raggiungono il picco intorno a 170 e scendono in modo simmetrico oltre i 190. L'asse verticale ha l'etichetta "Frequency", cioè i conteggi grezzi, e il titolo e l'etichetta dell'asse vengono dal nome della variabile.

Le impostazioni predefinite sono volutamente spartane. I soliti argomenti di abbellimento funzionano tutti:

hist(heights,
     main   = "Distribution of heights",
     xlab   = "Height (cm)",
     col    = "steelblue",
     border = "white")

col riempie le barre, border colora i loro contorni: border = "white" dà l'aspetto pulito a barre separate che vedi nella maggior parte delle pubblicazioni. Tutto ciò che la guida a plot() dice su colori e titoli vale anche qui senza modifiche.

Larghezza delle classi: l'argomento breaks

L'argomento più importante di hist() è breaks, perché la larghezza delle classi decide quale storia racconta il grafico. Stessi dati, due impostazioni:

hist(heights, breaks = 5)    # five wide bins: a crude, blocky bell
hist(heights, breaks = 30)   # thirty narrow bins: detail, plus noise

Con breaks = 5 l'istogramma è così grossolano che tutto sembra un'unica gobba liscia: un secondo gruppo o un vuoto nei dati sarebbero invisibili. Con breaks = 30 vedi la struttura fine, ma le oscillazioni casuali iniziano a travestirsi da caratteristiche reali. Nessuna delle due è "corretta"; la mossa onesta è provare qualche impostazione e vedere quali caratteristiche sopravvivono.

breaks accetta tre forme:

  • Un numero: breaks = 30 è un suggerimento per il numero di classi. R lo aggiusta per cadere su limiti ordinati, quindi potresti ottenere 28 o 33 classi. Sorprende tutti, almeno una volta.
  • Un vettore di punti di taglio: breaks = seq(140, 200, by = 5) fissa i bordi esatti delle classi, senza trattative. Usalo quando le classi devono essere allineate tra più istogrammi che stai confrontando.
  • Il nome di una regola: breaks = "FD" per Freedman-Diaconis, che sceglie la larghezza in base alla dispersione dei dati e alla dimensione del campione e si comporta bene con dati asimmetrici.

Istogrammi di densità e curva normale

Di default le altezze delle barre sono conteggi (freq = TRUE). Impostando freq = FALSE le barre vengono riscalate in modo che la loro area totale sia 1: la scala di densità. La forma non cambia, cambia l'asse verticale. Il motivo per farlo è che un istogramma di densità sta sulla stessa scala di una funzione di densità di probabilità, quindi puoi sovrapporre una curva teorica direttamente sopra i dati:

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() con add = TRUE disegna la curva a campana sopra l'istogramma esistente (la x dentro dnorm(x, ...) è un segnaposto che curve() riempie da sé, non una tua variabile). Se le barre aderiscono alla curva, un modello normale è ragionevole; dove se ne discostano, con una coda pesante o un secondo picco, al modello manca qualcosa. Senza freq = FALSE la curva striscia inutilmente sul fondo del grafico, perché conteggi e densità stanno su scale diverse.

I numeri dietro le barre

hist() non si limita a disegnare: restituisce la suddivisione in classi come lista. Con plot = FALSE salta del tutto il disegno e calcola soltanto, quindi questo lo puoi eseguire proprio qui:

h$counts è l'istogramma sotto forma di dati: ogni numero è l'altezza di una barra. La riga table(cut(...)) è l'equivalente in modalità testo: cut() divide i valori in classi, table() conta ogni classe, ed è un buon controllo da stampare prima di un grafico o al suo posto. Se assegni senza plot = FALSE (h <- hist(heights)), R disegna e restituisce la lista; l'assegnazione non sopprime il grafico.

Istogrammi con ggplot2

La versione ggplot2 sostituisce breaks con binwidth, che spesso è la manopola più naturale: dici quanto è larga una classe nelle unità dei dati invece di quante classi vuoi:

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 significa che ogni barra copre 5 cm. ggplot2 ti avvisa se lasci binwidth non impostato e usa in silenzio 30 classi di default: dai retta all'avviso, perché quel valore raramente è la larghezza giusta per i tuoi dati. Per un'occhiata veloce a una variabile, hist() richiede meno battute; ggplot2 si guadagna il posto quando l'istogramma ha bisogno di facet, gruppi o un tema coerente con il resto delle tue figure.

Cosa ti porti a casa

  • Un istogramma mostra la distribuzione di una variabile numerica: hist(x) e hai finito.
  • breaks è l'argomento che conta: un numero è solo un suggerimento, un vettore fissa i bordi esatti, "FD" sceglie una larghezza difendibile. Prova sempre più di un'impostazione.
  • freq = FALSE passa alla scala di densità, ed è ciò che permette a curve(dnorm(...), add = TRUE) di sovrapporre una curva normale in modo sensato.
  • hist(x, plot = FALSE) restituisce le classi come dati ($breaks, $counts, $mids); table(cut(x, breaks)) è l'equivalente solo testo.
  • In ggplot2, geom_histogram(binwidth = ...), e imposta binwidth tu stesso.

Prossimo passo: il boxplot, il grafico di distribuzione che dà il meglio quando confronti gruppi uno accanto all'altro.

Domande frequenti

Come si fa un istogramma in R?

Chiama hist(x) su un vettore numerico. R divide l'intervallo di x in classi (bin) e disegna una barra per classe, la cui altezza mostra quanti valori ci cadono dentro. Aggiungi breaks = per controllare il numero di classi e col = per colorare le barre.

Cosa fa l'argomento breaks in hist()?

Controlla la suddivisione in classi. Un singolo numero come breaks = 30 è un suggerimento su quante classi usare (R lo arrotonda a limiti ordinati), un vettore come breaks = seq(140, 200, by = 5) fissa i punti di taglio esatti, e breaks = "FD" usa la regola di Freedman-Diaconis.

Come si sovrappone una curva normale a un istogramma in R?

Disegna l'istogramma sulla scala di densità con freq = FALSE, poi aggiungi la curva con curve(dnorm(x, mean = mean(data), sd = sd(data)), add = TRUE). Sulla scala delle frequenze la curva resterebbe inutilmente schiacciata vicino allo zero, quindi freq = FALSE è indispensabile.

Qual è la differenza tra un istogramma e un grafico a barre?

Un istogramma divide in classi una variabile numerica, quindi l'asse orizzontale è una scala continua e le barre si toccano. Un grafico a barre confronta categorie distinte, quindi le barre sono separate. In R si usa hist() per i numeri e barplot() per i conteggi delle categorie.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA