giovedì 17 gennaio 2019

Grafici a scatola con i baffi (boxplot)

Il modo più semplice per generare i grafici a scatola con i baffi (box-and-whiskers plot, denominazione in genere abbreviata in boxplot) è impiegare la funzione boxplot() inclusa nel pacchetto base di R che utilizza i seguenti criteri di rappresentazione [1]:
→ le scatole (box) includono il 50% delle osservazioni;
→ il bordo inferiore delle scatole corrisponde al 25° percentile o primo quartile (Q1);
→ la linea interna alle scatole corrisponde al 50° percentile o secondo quartile (Q2) ovvero alla mediana;
→ il bordo superiore delle scatole corrisponde al 75° percentile o terzo quartile (Q3);
→ i baffi (whiskers) corrispondono al valore minimo (baffo inferiore) e al valore massimo (baffo superiore) osservati dopo avere escluso gli outliers (vedi sotto);
→ la differenza interquartile [2] viene definita come IQR = Q3 – Q1 ovvero come differenza tra il valore corrispondente al terzo quartile (Q3) e il valore corrispondente al primi quartile (Q1);
→ i valori inferiori a Q- 1.5 · IQR e i valori superiori a Q+ 1.5 · IQR sono considerati outliers (dati anomali o dati aberranti), sono esclusi dal computo dei valori minimo e massimo (vedi sopra), e sono riportati come punti singoli separati.

I boxplot forniscono una analisi non parametrica dei dati complementare a quella numerica. Qui li impieghiamo per effettuare l'analisi della concentrazione degli eritrociti (globuli rossi) nel sangue rilevata in 202 atleti australiani riportata nella colonna/variabile rcc della tabella ais inclusa nel pacchetto DAAG. Accertatevi di avere installato il pacchetto o in alternativa procedete come indicato in [3]. La conclusione? 

Con R è possibile realizzare grafici a scatola con i baffi con una sola e semplicissima riga di codice!

Iniziamo con queste quattro righe di codice, copiatele e incollatele nella Console di R e premete ↵ Invio:

# GRAFICI A SCATOLA CON I BAFFI suddivisi in base a un fattore
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
windows() # apre e inizializza una nuova finestra grafica 
#
boxplot(rcc~sport, data=ais, horizontal=FALSE, main="Eritrociti per sport praticato", xlab="Sport praticato", ylab="Eritrociti in 10^12/L", notch=FALSE, col="yellow") # eritrociti per ciascuno sport praticato
#

Le prime due righe si limitano a:
→ caricare con la funzione library() il pacchetto DDAG che include il set di dati ais;
 aprire una finestra grafica con la funzione  windows().

Per tracciare il boxplot viene impiegata una sola riga di codice con la funzione boxplot() e con questi argomenti:
→ rcc~sport che indica che la rappresentazione degli eritrociti sotto forma di boxplot deve essere effettuata aggregando (~) i valori della variabile eritrociti (rcc) nei sottoinsiemi corrispondenti ai valori del fattore/variabile sport (B_Ball, Field, Gym, Netball, Row, Swim, T_400m, T_Sprnt, Tennis, W_Polo);
data=ais che specifica il nome della tabella che contiene la variabile rcc e la variabile sport - notare che questo argomento è superfluo se vi riferite alle variabili della tabella ais indicandole con il nome completo ais$nomedellavariabile, ovvero nel nostro caso ais$rcc, ais$sex, ais$sport, e così via;
→ horizontal=FALSE che indica che i boxplot devono essere orientati verticalmente;
main="..." che riporta il titolo del grafico;
xlab="..." che riporta l'etichetta da applicare all'asse x delle ascisse;
ylab="..." che riporta l'etichetta da applicare all'asse y delle ordinate:
notch=FALSE che esclude dai boxplot la rappresentazione dell'incisura che riporta i limiti di confidenza al 95% della mediana dei valori osservati;
col="..." che definisce il colore di riempimento dei boxplot.


Sull'asse orizzontale apparentemente non c'è spazio sufficiente per riportare le denominazioni di tutti gli sport: ma se "afferrate" il lato sinistro della finestra con il mouse ed estendete la finestra grafica in orizzontale vedete comparire le denominazioni mancanti.


In questo secondo script rielaboriamo i dati aggregando i valori per sesso con l'argomento rcc~sex:

# GRAFICI A SCATOLA CON I BAFFI con i limiti di confidenza della mediana
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
windows() # apre e inizializza una nuova finestra grafica 
#
boxplot(rcc~sex, data=ais, horizontal=FALSE, main="Eritrociti per sesso", xlab="Sesso", ylab="Eritrociti in 10^12/L", notch=TRUE, col="green") # eritrociti per sesso
#

Impiegando l'argomento notch=TRUE ora sui lati dei boxplot sono comparse le tacche (notch) o se preferite le incisure che rappresentano i limiti di confidenza al 95% della mediana.


Questo corrisponde ad 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, come in questo caso, la conclusione è che le mediane delle due distribuzioni differiscono significativamente.

Il fatto interessante è quindi che una rappresentazione grafica può essere impiegata non solo per effettuare una analisi esplorativa dei dati, ma addirittura per effettuare un test statistico (un confronto tra mediane) che ci conferma il fatto che la mediana della concentrazione degli eritrociti nelle atlete è inferiore a quella dagli atleti (è all'incirca di 4.4 · 10¹²/L contro 5.0 · 10¹²/L) e che la differenza tra le mediane, all'incirca di 0.6 · 10¹²/L, è statisticamente significativa come risulta dal confronto fra i due boxplot.

Da notare che quando nella funzione boxplot() si pone l'argomento notch=TRUE potrebbe comparire nella Console di R un messaggio che avverte che in alcuni casi le incisure sono uscite dai bordi della scatola e che suggerisce di valutare l'opportunità di sostituire l'argomento con notch=FALSE.

Questo vi accadrà quando eseguite questo terzo script, che applica l'argomento notch=TRUE ai boxplot differenziati per sport:

# GRAFICI A SCATOLA CON I BAFFI con i limiti di confidenza della mediana
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
windows() # apre e inizializza una nuova finestra grafica
#
boxplot(rcc~sport, data=ais,  horizontal=FALSE, cex.axis=0.8, las=2, main="Eritrociti per sport praticato", xlab="Sport praticato", ylab="Eritrociti in 10^12/L", notch=TRUE, col="green") # eritrociti per ciascuno sport praticato
#

In questo caso il grafico


evidenzia la comparsa del problema per gli sport Field, Gym, T_sprnt, Tennis e nella Console di R viene riportato questo messaggio:

> boxplot(rcc~sport, data=ais,  horizontal=FALSE, cex.axis=0.8, las=2, main="Eritrociti per sport praticato", xlab="Sport praticato", ylab="Eritrociti in 10^12/L", notch=TRUE, col="green") # eritrociti per ciascuno sport praticato
Messaggio di avvertimento:
In (function (z, notch = FALSE, width = NULL, varwidth = FALSE,  :
alcune tacche sono andate fuori dai cardini ('box'): potresti impostare notch=FALSE
> #

Il problema è causato dal fatto che per gli sport in questione il numero delle osservazioni è troppo ridotto. In questi casi vi sono solamente due modi per superare il problema:
 mettere l'argomento notch=FALSE, come consigliato nella nota "potresti impostare notch=FALSE", e quindi rinunciare al "test grafico" di significatività;
 aumentare adeguatamente, sempre che sia possibile farlo, il numero delle osservazioni.

Da notare che nella funzione boxplot() sono stati aggiunti due argomenti che consentono di ricavare lo spazio necessario per riportare sotto ai boxplot degli eritrociti le denominazioni degli sport senza dover ridimensionare la finestra grafica:
→ l'argomento cex.axis=0.8 che riduce lievemente la dimensione dei caratteri;
→ l'argomento las=2 che ruota verticalmente le etichette.

Ora copiate questo script, incollatelo nella Console di R e premete ↵ Invio:

# GRAFICI A SCATOLA CON I BAFFI con due grafici nella stessa immagine
#
library(DAAG) # carica il pacchetto DAAG incluso il set di dati ais
windows() # apre e inizializza una nuova finestra grafica
par(mfrow=c(1,2)) # due grafici in una riga e due colonne
#
boxplot(ais$pcBfat~ais$sport, horizontal=TRUEboxwex=0.4, cex.axis=0.8las=1, xlab="Grasso corporeo in %", ylab="Sport praticato", notch=FALSE, col="yellow") # valori della percentuale di grasso corporeo aggregati per sport
#
boxplot(ais$wt~ais$sport, horizontal=TRUE, boxwex=0.4, cex.axis=0.8, las=1, xlab="Peso corporeo in kg", ylab="Sport praticato", notch=FALSE, col="yellow") # [2] valori del peso corporeo aggregati per sport
#

In questo caso, per riportare due grafici affiancati:
 con par(mfrow=c(1,2)) è stata predisposta la suddivisione della finestra in 1 riga e 2 colonne;
 i boxplot sono riportati in orizzontale (horizontal=TRUE);
→ la larghezza dei box è stata ridotta (boxwex=0.4);
→ è impiegato l'argomento cex.axis=0.8 che riduce lievemente la dimensione dei caratteri;
 le etichette delle ascisse sono riportate in orizzontale (las=1)
→ non vengono riportate le incisure (notch=FALSE) che rappresentano i limiti di confidenza al 95% della mediana.

Inoltre qui, in assenza dell'argomento data=ais, nella funzione boxplot() sono stati  riportati per intero – cioè con il prefisso ais$ che indica la tabella che le contiene – i nomi della variabili.



Con quest'ultimo script riportiamo in un unico grafico i boxplot suddivisi in base a due fattori: sport e sesso. Questa volta la novità consiste in una legenda liberamente posizionabile: dopo avere tracciato i grafici separati per sport praticato e per sesso, lo script rimane in attesa. A questo punto bisogna posizionare il mouse dove si vuole che compaia la legenda [4] e fare click con il tasto sinistro del mouse per farla comparire e terminare lo script.

# GRAFICI A SCATOLA CON I BAFFI suddivisi in base a due fattori
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
windows() # apre e inizializza una nuova finestra grafica 
#
boxplot(rcc~sex+sport, data=ais, horizontal=FALSE, boxwex=0.4, cex.axis=0.8, las=2, main="Eritrociti per sport praticato e per sesso", xlab="", ylab="Eritrociti in 10^12/L", notch=FALSE, col=c("green", "yellow")) # eritrociti per ciascuno sport praticato
#
legend(locator(1), legend=c("sesso f","sesso m"), fill=c("green", "yellow")) # posiziona la legenda
#

Il codice non consente di spostare la legenda. Se non si è soddisfatti della sua posizione, è necessario rieseguire l’intero blocco di codice e fare nuovamente click con il tasto sinistro del mouse nel punto in cui si vuole posizionare la legenda.


Nella funzione boxplot() sono ora impiegati tre argomenti per risolvere il problema dello spazio necessario per riportare nella finestra grafica i boxplot degli eritrociti per tutti gli sport e per entrambi i sessi:
→ l'argomento boxwex=0.4 che riduce la larghezza dei boxplot;
→ l'argomento cex.axis=0.8 che riduce lievemente la dimensione dei caratteri;
→ l'argomento las=2 che ruota verticalmente le etichette.

La legenda viene realizzata mediante la funzione legend() impiegando come argomenti:
→ la funzione locator() che resta in attesa, legge la posizione del cursore grafico quando viene fatto click con il tasto sinistro del mouse, e posiziona la legenda;
→ legend= che specifica le due righe di testo che compaiono nella legenda;
→ fill= che determina la comparsa accanto alle righe di testo di due quadrati dei colori specificati.

Chiudo con tre suggerimenti che potrebbero essere utili:
→ trovate come combinare adeguatamente in un'unica immagine più grafici a scatola con i baffi nel post Inserire più grafici nella stessa immagine;
→ potete combinare i grafici a scatola con i baffi con il kernel density plot dei dati impiegando i grafici a violino (violin plot) [5];
→ quando i dati sono pochi, e preferite conservare il dettaglio dei singoli valori, potete impiegare in alternativa grafici a punti (dotplot).


----------

[1] Digitate help(boxplot) nella Console di R per la documentazione della funzione boxplot().

[2] In italiano oltre che differenza interquartile si impiega anche scarto o ampiezza o range interquartile, in inglese si impiega Inter Quartile Range, da cui IQR.

[3] Vedere il post Il set di dati ais nel quale trovate anche come caricare i dati della tabella senza impiegare il pacchetto DAAG

[4] Più precisamente fare click con il tasto sinistro del mouse nel punto in cui si vuole posizionare l'angolo superiore sinistro della legenda.

[5] Richiede l'installazione del pacchetto aggiuntivo ggplot2.

Nessun commento:

Posta un commento