I grafici a scatola con i baffi (o box plot o boxplot) sono un ottimo esempio per illustrare alcune delle rappresentazioni grafiche dei dati che si possono realizzare con il pacchetto ggplot2. Come con gli altri post analoghi o scopo è aiutare a rompere il ghiaccio con le funzioni di questo pacchetto, che possono risultare ostiche quando le si affronta per la prima volta.
Oltre al pacchetto ggplot2 [1] dovete accertarvi di avere installato – o dovete scaricare anche – il pacchetto DAAG [2] che contiene il set di dati ais impiegati nell'esempio, il pacchetto gridExtra che consente di combinare i grafici in una sola figura e il pacchetto forcats per l'ordinamento in base alla mediana dei gruppi.
Copiate e incollate nella Console di R questo script e premete ↵ Invio.
# BOXPLOT con ggplot
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
# boxplot dell'emoglobina per sesso
plot1 <- ggplot(ais, aes(x=sex, y=hg)) + geom_boxplot(aes(fill=sex))
#
# riposiziona la legenda in basso
plot2 <- ggplot(ais, aes(x=sex, y=hg)) + geom_boxplot(aes(fill=sex)) + theme(legend.position="bottom")
#
# aggiunge etichette degli assi e titolo
plot3 <- ggplot(ais, aes(x=sex, y=hg)) + geom_boxplot(aes(fill=sex)) + xlab("Sesso") + ylab("Emoglobina (g/dL)") + ggtitle("Boxplot per sesso")
#
# centra il titolo e personalizza la legenda
plot4 <- ggplot(ais, aes(x=sex, y=hg)) + geom_boxplot(aes(fill=sex), notch=TRUE) + xlab("Sesso") + ylab("Emoglobina (g/dL)") + ggtitle("Boxplot per sesso") + theme(plot.title=element_text(hjust=0.5)) + labs(fill="Legenda") + scale_fill_hue(labels=c("f=donna", "m=uomo"))
#
# combina i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2)
#
Dopo avere caricato i pacchetti necessari, sono generati quattro boxplot che sono salvati separatamente per essere al termine (per semplicità) combinati in una sola figura.
Per realizzare il primo grafico (plot1) viene impiegata innanzitutto la funzione ggplot() – che inizializza l'oggetto al quale sono collegate con il segno più [+] le successive funzioni, che sviluppano la grafica – che prevede:
→ come primo argomento il nome della tabella che contiene i dati (ais);
→ come secondo argomento la funzione aes() che specifica di riportare in ascisse (x=) la variabile (fattore) sesso sex e in ordinate (y=) la variabile (numerica) hg che rappresenta la concentrazione di emoglobina espressa in grammi per decilitro di sangue (g/dL).
Alla funzione ggplot() viene quindi collegata con il segno più [+] la funzione geom_boxplot() che realizza il grafico a scatola con i baffi specificando per il colore di riempimento (fill) dei boxplot una gamma di colori automatica con un colore differente per ciascun sesso (sex).
Da notare subito che questa è la struttura base che rimane identica in tutti e quattro i grafici realizzati, che si differenziano tra loro per le componenti grafiche via via aggiunte.
Il secondo grafico (plot2) quindi riprende tal quale la precedente struttura base e aggiunge semplicemente, tramite la funzione theme(), il posizionamento della legenda (legend.position) in basso sotto al grafico ("bottom").
Nel terzo grafico (plot3) viene eliminato il riposizionamento della legenda che viene pertanto lasciata nella posizione laterale prevista di default, quindi:
→ con la funzione xlab() viene aggiunta l'etichetta dell'asse delle ascisse;
→ con la funzione ylab() viene aggiunta l'etichetta dell'asse delle ordinate;
→ con la funzione ggtitle() viene riportato in alto un titolo per il grafico.
Il quarto grafico (plot4) riprende in toto le funzioni del terzo grafico e in aggiunta:
→ con notch=TRUE riporta sui box i limiti di confidenza al 95% della mediana;
→ con l'argomento plot.title della funzione theme() centra il titolo;
→ con labs() riporta l'intestazione della legenda;
→ con scale_fill_hue() riporta nella legenda le etichette che identificano i dati.
Infine con la funzione grid.arrange() i quattro grafici sono combinati in un'unica figura.
Copiate e incollate nella Console di R questo secondo script e premete ↵ Invio.
# BOXPLOT con ggplot
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
library(forcats) # carica il pacchetto per l'ordinamento in base alla mediana
#
# boxplot dell'emoglobina per sport con dotplot
plot1 <- ggplot(ais, aes(x=sport, y=hg)) + geom_boxplot(aes(fill=sport)) + ylim(10, 20) + theme(legend.position="none") + geom_dotplot(binaxis='y', stackdir='center', binwidth=0.3, color="black", fill="grey")
#
# boxplot con incisura e ordinati in base alla mediana
plot2 <- ggplot(ais, aes(x=fct_reorder(sport, hg, median), y=hg)) + geom_boxplot(aes(fill=sport), notch=TRUE) + ylim(10, 20) + theme(legend.position="none")
#
# boxplot per sesso con etichette in verticale e ampiezza dei boxplot ridotta
plot3 <- ggplot(ais, aes(x=fct_reorder(sport, hg, median), y=hg)) + geom_boxplot(aes(fill=sex), width=.75) + ylim(10, 20) + theme(legend.position="none") + theme(axis.text.x=element_text(angle=90, hjust=1))
#
# unisce i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, nrow=3, ncol=1)
#
Il primo grafico (plot1) rispetto a quanto riportato nello script precedente prevede queste modifiche:
→ il fattore sesso viene sostituito con il fattore sport;
→ con la funzione ylim() viene personalizzata la scala delle ordinate;
→ con il valore "none" dell'argomento legend.position della funzione theme() viene eliminata la legenda;
→ con la funzione geom_dotplot() ai boxplot sono sovrapposti i grafici a punti (dotplot) centrati ('center') lungo l'asse delle ordinate ('y') con un diametro oppertunamente ridotto (0.3), tracciati in nero ("black") con riempimento in colore grigio ("grey").
Eliminata la parte più verbosa rappresentata dai grafici a punti (dotplot) sovrapposti, i grafici seguenti sono realizzati con piccole modifiche del codice.
Nel secondo grafico (plot2) viene eliminato il riposizionamento della legenda che viene pertanto lasciata nella posizione laterale prevista di default, quindi:
→ con la funzione fct_reoder() i box per sport sono riportati ordinati in base alla mediana (median) dell'emoglobina (hg);
→ con notch=TRUE viene riportata in ciascun box l'incisura che rappresenta i limiti di confidenza al 95% della mediana. Questo fornisce un test per la significatività della differenza tra le mediane: se le tacche o incisure di due boxplot non si sovrappongono, pur sovrapponendosi in parte le distribuzioni dei dati, le mediane delle due distribuzioni differiscono significativamente. Da notare che nella Console di R compare quattro volte un messaggio che avverte che le incisure sono uscite dai bordi della scatola negli sport Gym, Swim e W_Polo come risulta evidenziato anche nei rispettivi boxplot: la ragione è che in questi casi il numero delle osservazioni è troppo ridotto e pertanto non è possibile trarre dai dati in questione conclusioni statisticamente valide.
Nel terzo grafico (plot3) infine i boxplot sono ancora ordinati in base alla mediana mentre:
→ in ciascuno sport sono ulteriormente suddivisi per sesso (fill=sex);
→ sono lievemente ristretti (width=.75);
→ con la funzione theme() le etichette sull'asse delle ascisse (axis.text.x) sono disposte in verticale.
Questa è la figura risultante.
Nota: i grafici a scatola con i baffi possono esser realizzati anche impiegando le sole funzioni contenute della installazione base di R [3] con risultati più che adeguati nella maggior parte dei casi. Tuttavia con il pacchetto ggplot2 potete ottenere facilmente ulteriori e interessanti rappresentazioni.
----------
[1] Vedere la documentazione e il manuale di riferimento su:
https://cran.r-project.org/web/packages/ggplot2/index.html
[2] Vedere il post Il set di dati ais nel quale trovate anche come caricare i dati della tabella senza impiegare il pacchetto DAAG.
Nessun commento:
Posta un commento