Menu

Grafico a barre in R: barplot() da conteggi e tabelle

Come creare un grafico a barre in R con barplot(): da un vettore con nomi o da table(), barre affiancate e impilate da una matrice, stile, e geom_col contro geom_bar.

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

I grafici a barre confrontano categorie

Un grafico a barre risponde alla domanda "quanto di ciascuno?": una barra per categoria, con la lunghezza della barra che mostra il valore della categoria. In R la funzione di base è barplot(), e il suo input è semplicemente un vettore di altezze. Dai dei nomi al vettore e i nomi diventano le etichette sotto le barre:

visits <- c(Mon = 42, Tue = 51, Wed = 47, Thu = 60, Fri = 78)

barplot(visits,
        main = "Store visits by day",
        ylab = "Visits")

Cinque barre grigie, etichettate per giorno, che salgono da un lunedì modesto fino a un picco il venerdì alto quasi il doppio. Niente da installare, niente da configurare: se sai costruire un vettore con nomi, sai farne un grafico.

Gli editor eseguibili di questa pagina mostrano solo output testuale, quindi le chiamate a barplot() qui sono frammenti statici da incollare in una sessione R locale. Il passaggio di conteggio che le precede però funziona benissimo, ed è quello che conta di più.

Il flusso reale: prima table(), poi barplot()

In pratica raramente hai altezze già contate e in ordine. Hai una colonna grezza di etichette di categoria, una riga per risposta al sondaggio, per ordine, per utente, e il conteggio è il vero lavoro. table() lo fa in una chiamata, e il suo output è un vettore di conteggi con nomi, che è esattamente ciò che vuole barplot():

Poi il grafico è una riga in più:

barplot(sort(t, decreasing = TRUE),
        main = "Survey responses",
        ylab = "Count")

Questi due passi, table() e poi barplot(), sono il flusso più comune in assoluto per i grafici a barre in R. Ordinare prima la tabella è un miglioramento che non costa nulla: barre ordinate per altezza si leggono più in fretta di barre in ordine alfabetico, a meno che le categorie abbiano un ordine naturale (giorni, mesi, livelli di dose). In quel caso un factor con i livelli nell'ordine giusto impedisce a table() di metterli in ordine alfabetico. Per barre che richiedono una vera aggregazione, cioè somme o medie per gruppo invece di conteggi di righe, fai prima il passaggio di group-by-summarize e passa il risultato a barplot().

Etichette e stile

Di solito le etichette vengono dai nomi del vettore, ma names.arg le sostituisce: utile quando i codici nei dati non sono adatti a un pubblico:

barplot(visits,
        names.arg = c("Monday", "Tuesday", "Wednesday",
                      "Thursday", "Friday"),
        col    = "steelblue",
        border = NA,
        main   = "Store visits by day",
        las    = 2)
  • col riempie le barre; passa un vettore per colorare ogni barra singolarmente, ma resisti all'arcobaleno per default: il colore dovrebbe avere un significato, come evidenziare l'unica barra di cui stai parlando.
  • border = NA rimuove i contorni delle barre per un aspetto più pulito.
  • las = 2 ruota le etichette degli assi in perpendicolare all'asse: è la soluzione quando nomi di categoria lunghi si sovrappongono. Abbinalo a un margine inferiore più grande (par(mar = c(8, 4, 4, 2))) se i nomi sono davvero lunghi.

Barre raggruppate e impilate da una matrice

Per mostrare due dimensioni categoriali insieme, per esempio le vendite per canale e per trimestre, passa a barplot() una matrice. Ogni colonna diventa una posizione sull'asse delle categorie e le righe diventano le sotto-barre:

sales <- matrix(c(12, 18,   15, 22,   20, 19,   24, 27),
                nrow = 2,
                dimnames = list(c("Online", "Retail"),
                                c("Q1", "Q2", "Q3", "Q4")))

# Grouped: rows stand next to each other within each quarter
barplot(sales, beside = TRUE,
        col = c("steelblue", "orange"),
        legend.text = rownames(sales),
        main = "Sales by channel and quarter")

# Stacked: rows pile up into one total bar per quarter (the default)
barplot(sales, beside = FALSE,
        col = c("steelblue", "orange"),
        legend.text = rownames(sales))

beside = TRUE mette i due canali fianco a fianco dentro ogni trimestre: la scelta migliore quando vuoi confrontare i canali direttamente. La versione impilata predefinita mette in risalto il totale di ogni trimestre, con la suddivisione mostrata dentro ogni barra; è onesta per i totali ma rende difficile confrontare i segmenti interni tra una barra e l'altra, perché le loro basi si spostano. legend.text = rownames(sales) aggiunge la legenda che rende leggibili entrambe le versioni.

Un'altra opzione: horiz = TRUE dispone le barre lungo l'asse orizzontale. È il layout più gentile quando hai molte categorie con nomi lunghi: ogni etichetta sta sulla sua riga accanto alla sua barra, senza bisogno di ruotarla.

Grafico a barre o istogramma?

Chi cerca li confonde di continuo, e la distinzione vale trenta secondi: un grafico a barre confronta categorie distinte. L'asse è un insieme di etichette, le barre sono separate e riordinarle è lecito. Un istogramma raggruppa in classi una variabile numerica. L'asse è una scala continua, le barre si toccano perché le classi sono intervalli consecutivi e riordinarle non avrebbe senso. Se la tua colonna contiene parole ("Yes", "Chrome", "Q3"), ti serve barplot(table(x)). Se contiene misure (altezze, prezzi, tempi di risposta), ti serve l'istogramma con hist(x).

ggplot2: geom_col contro geom_bar

La versione ggplot2 esiste in due geom, distinti a seconda che il conteggio sia già stato fatto:

library(ggplot2)

# geom_bar(): raw observations in, counting done for you
ggplot(survey, aes(x = response)) +
    geom_bar(fill = "steelblue")

# geom_col(): heights already computed, one row per bar
totals <- data.frame(day = c("Mon", "Tue", "Wed", "Thu", "Fri"),
                     visits = c(42, 51, 47, 60, 78))

ggplot(totals, aes(x = day, y = visits)) +
    geom_col(fill = "steelblue")

geom_bar() è table() incorporato nel grafico: prende una riga per osservazione e conta. geom_col() prende dati già aggregati e associa una colonna y all'altezza della barra, l'equivalente del classico barplot(). Dare a geom_bar() dati già contati è la trappola tipica di chi inizia: conta le righe (una ciascuna) e tutte le barre escono alte uguali.

Cosa ti porti a casa

  • barplot(heights) disegna un vettore con nomi, e table(x) produce esattamente quella forma dai dati di categoria grezzi: barplot(table(x)) è l'idioma di base.
  • Ordina la tabella (o imposta i livelli del factor) prima di disegnare; l'ordine delle barre fa parte del messaggio.
  • Una matrice produce barre raggruppate (beside = TRUE) o impilate (predefinito); aggiungi legend.text = rownames(m).
  • names.arg, col, las = 2 e horiz = TRUE gestiscono le etichette; le barre orizzontali sono le migliori per i nomi lunghi.
  • Categorie → grafico a barre; classi numeriche → istogramma. In ggplot2: righe grezze → geom_bar(), altezze calcolate → geom_col().

Prossimo passo: ggplot2 vero e proprio, la grammatica che costruisce tutti questi grafici, e molti altri, con gli stessi pochi pezzi componibili.

Domande frequenti

Come si crea un grafico a barre in R?

Chiama barplot() su un vettore di altezze. Dai dei nomi al vettore, oppure costruiscilo con table(), il cui output ha già i nomi, e ogni elemento diventa una barra con la sua etichetta: barplot(table(df$category)).

Come si crea un barplot raggruppato o impilato in R?

Passa una matrice. Ogni colonna diventa una posizione sull'asse delle categorie; beside = TRUE disegna le righe come barre una accanto all'altra (raggruppate), mentre il valore predefinito beside = FALSE le impila. Aggiungi legend.text = rownames(m) così chi legge può distinguere le righe.

Qual è la differenza tra barplot() e hist() in R?

barplot() confronta categorie distinte: una barra per categoria, barre separate. hist() raggruppa una variabile numerica in intervalli consecutivi: le barre si toccano perché l'asse è una scala continua. Se la tua variabile contiene parole, ti serve barplot(table(x)); se contiene numeri, ti serve hist(x).

Meglio geom_bar o geom_col in ggplot2?

geom_bar() conta al posto tuo: le dai le osservazioni grezze e lei calcola il totale di ogni categoria. geom_col() disegna valori che hai già calcolato: le dai una riga per barra più una colonna con l'altezza. Usare geom_bar() con dati già contati è l'errore classico; in quel caso serve geom_col().

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA