mercoledì 25 novembre 2020

Grafici a punti (dotplot)

I grafici a punti (o se preferite dotplot) rappresentano una interessante alternativa ai grafici a scatola con i baffi nei casi di distribuzioni univariate che includono pochi dati e per le quali non volete perdere il dettaglio dei singoli valori.

Per eseguire i due script che seguono è necessario scaricare dal CRAN il pacchetto ggplot2 [1] e il pacchetto gridExtra [2]. Accertatevi inoltre di avere già installato il pacchetto DAAG che contiene i dati impiegati nello script, o in alternativa installatelo procedendo come indicato nel post Il set di dati ais. Copiate questo primo script, incollatelo nella Console di R e premete ↵ Invio.

# UN GRAFICO A PUNTI (DOTPLOT)
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto necessario per la grafica
#
ggplot(ais, aes(x=sport, y=hg, fill=sport)) + geom_dotplot(method="dotdensity", binaxis='y', stackdir="center", stackratio=1, dotsize=1, binwidth=0.2, show.legend=FALSE) + coord_cartesian(ylim=c(10, 20)) + labs(title="Concentrazione dell'emoglobina nel sangue per sport praticato", x="Sport praticato", y="Emoglobina (g/dL)") + theme_classic() # traccia dotplot dell'emoglobina per sport
#


Come vedete il pacchetto ggplot2 consente di realizzare il grafico a punti o dotplot impiegando di fatto una sola riga di codice che include cinque funzioni concatenate:
la funzione ggplot() che specifica i dati da impiegare (ais) e con la funzione aes() specifica di realizzare il grafico a punti separatamente per ciascuno sport praticato (x=sport) per la variabile emoglobina (y=hg);
la funzione geom_dotplot() che di fatto realizza il grafico con una serie piuttosto articolata di argomenti per il dettaglio dei quali rimando alla documentazione della funzione inclusa nel manuale di riferimento del pacchetto [1];
la funzione coord_cartesian() che viene impiegata per stabilire (ylim=) valore minimo e valore massimo pare rappresentare la distribuzione dei punti sull'asse delle y;
la funzione labs() che molto banalmente riporta titolo ed etichette degli assi;
la funzione theme_classic() che definisce “il look” del grafico.

Se guardate alla struttura dei dati contenuti nell'oggetto ais digitando
str(ais)
notate che i dati impiegati per realizzare il grafico sono strutturati (l'ordine e il numero delle variabili è ovviamente indifferente) come segue

fattore valore
   A      4               
   B      2
   B      5
   A      4
   C      3
   A      5
   C      2
   B      7
  ...    ...

dove nel caso specifico il fattore è lo sport praticato contenuto nella variabile sport (riportata sull'asse orizzontale x) e il valore è la concentrazione di emoglobina contenuta nella variabile hg (riportata sull'asse verticale y).

E questo è il grafico risultante.









fare click sull'immagine per ingrandirla










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

# DUE GRAFICI A PUNTI (DOTPLOT) AFFIANCATI
#

library(DAAG) # carica il pacchetto DAAG incluso il set di dati ais
#

library(ggplot2) # carica il pacchetto
plot1 <- ggplot(ais, aes(x=sex, y=hg, fill=sex)) + geom_dotplot(method="dotdensity", binaxis='y', stackdir="center", stackratio=1, dotsize=0.7, binwidth=0.2, show.legend=FALSE) + coord_cartesian(ylim=c(10, 20)) + labs(title="Emoglobina per sesso", x="Sesso", y="Emoglobina (g/dL)") + theme_classic() # dotplot dell'emoglobina per sesso
plot2 <- ggplot(ais, aes(x=sex, y=hc, fill=sex)) + geom_dotplot(method="dotdensity", binaxis='y', stackdir="center", stackratio=1, dotsize=1, binwidth=0.2, show.legend=FALSE) + coord_cartesian(ylim=c(35, 50)) + labs(title="Ematòcrito per sesso", x="Sesso", y="Ematòcrito (%)") + theme_classic() # dotplot dell'ematòcrito per sesso
#
library(gridExtra) # carica il pacchetto con la funzione necessaria per realizzare i grafici affiancati
grid.arrange(plot1, plot2, nrow = 1) # i due grafici sono affiancati orizzontalmente
#


Il codice per realizzare il grafico riportato nello script precedente viene in questo secondo script replicato due volte, per realizzare due grafici, e di fatto è sempre lo stesso tranne che per due aspetti:
→ il grafico a punti viene ora realizzato per sesso (x=sex) per la variabile ematòcrito (y=hc);
→ per affiancare i due grafici, dell'emoglobina per sesso e dell'ematòcrito per sesso, viene impiegata la funzione grid.arrange() inclusa nel pacchetto gridExtra [2] che consente di superare i limiti della analoga funzione par(mfrow=...) del pacchetto base di R [3].

Questo è il risultato.









fare click sull'immagine per ingrandirla










Per adattare lo script ai vostri dati servirà un po' più di lavoro del solito a causa della articolazione degli argomenti impiegati: ma si tratta di una opportunità per familiarizzare con le funzioni del pacchetto ggplot2 [1].

Ricordo infine che, impiegando l'utilità riportata nel post Salvare i grafici di R in un file, potete anche salvare le immagini realizzate con R, come quelle qui riportate, sotto forma di file .bmp, .jpeg, .png, .pdf, .ps per poterle stampare, archiviare, inserire in una pubblicazione, in un post o in un sito web.


----------

[1] Il manuale di riferimento Package ‘ggplot2’ lo trovate facendo click sul link Reference manual nella pagina di documentazione del pacchetto. URL consultato il 2/10/2020: https://bit.ly/3ioEJfE

[2] Il manuale di riferimento Package ‘gridExtra’ lo trovate facendo click sul link Reference manual nella relativa pagina di documentazione del pacchetto. URL consultato il 2/10/2020: https://bit.ly/36qc9Ip

[3] Alcuni esempi di impiego della funzione par(mfrow=...) sono riportati nel post Inserire più grafici nella stessa immagine.


giovedì 19 novembre 2020

Link ai file di dati (ripristino)

I link ai file di dati sono stati ripristinatiPer i dettagli sulle varie modalità che si hanno a disposizione per scaricare i file di dati di esempio impiegati nei post si rimanda alla pagina Dati,

[vedi Link ai file di dati]


mercoledì 18 novembre 2020

Link ai file di dati

Attenzione: a causa di un problema momentaneo i link ai file contenenti i dati di esempio di volta in volta riportati nei singoli post non funzionano, tuttavia i file di dati possono essere scaricati sia singolarmente sia sotto forma di un unico file .zip (in quest'ultimo caso fate click su Code quindi su Download ZIPda GitHub al link http://bit.ly/32KRTvC 

I link ai file di dati, sia quelli contenuti nei singoli post sia quelli omnicomprensivi riportati alla pagina Dati, saranno ripristinati a breve, grazie per la comprensione.

[vedi Link ai file di dati, ripristino]


domenica 4 ottobre 2020

Grandezze e unità di misura

Se è vero che la statistica è la tecnica che consente di fornire un supporto scientifico alle evidenze fornite dalle misure [di qualsivoglia fenomeno qualitativo o quantitativo], ci sono dal punto di vista metodologico, nelle misure, quattro passaggi sull'importanza dei quali non mi stancherò mai di richiamare l'attenzione:
→ la necessità, nel caso di scale numeriche, di impiegare un sistema di unità di misura razionale, documentato e condiviso quale è il Sistema internazionale di unità (SI), applicandone integralmente e senza eccezioni le indicazioni formali che sono in realtà più che mai sostanziali [1, 2];
→ la necessità di impiegare le regole, una delle quali sistematicamente disattesa, che indicano come separare i decimali e come raggruppare le cifre.

Qualcuno potrà obiettare che nell'ambito della statistica si tratta di aspetti marginali. Sarà anche vero: tuttavia sono convinto della necessità di richiamare l'attenzione su questi passaggi in quanto, essendo dati per ovvi e scontati senza il minimo di approfondimento che richiederebbero, sono ancor oggi fonte di inesattezze tanto banali quanto fastidiose, che possono essere facilmente evitate seguendo le indicazioni delle fonti che ho riportato qui sopra.

Aggiungo qualche parola in più in merito a grandezze e unità di misura. Discendente diretto del sistema metrico decimale originato dalla rivoluzione francese (fondato su metro e kilogrammo) e del successivo sistema MKSA (fondato su metro, kilogrammo, secondo, ampere e conosciuto anche come Sistema Giorgi in onore del proponente italiano Giovanni Giorgi), il Sistema internazionale di unità (SI), accettato dalla Comunità Economica Europea (CEE) nel 1980 e divenuto legale in Italia nel 1982, il giorno 20 maggio 2019 ha visto cambiare le definizioni di chilogrammo, ampere, kelvin e mole [2]. Lo scopo di questo cambiamento è basare le sette unità di misura fondamentali del SI sulle leggi della fisica, dando loro un fondamento solido, immutabile nel tempo e nello spazio.

Ho riassunto brevemente la storia delle unità di misura, dall'antichità al cambiamento epocale del SI avvenuto il 20 maggio 2019, in un ebook, disponibile facendo click su questa immagine del logo del nuovo SI


Per scaricare sul PC o tablet o smartphone il libro in formato
.pdf, dopo avere aperto il libro online con l'opzione Leggi, fate click su I miei libri quindi fate click sui tre puntini disposti verticalmente in basso a destra sulla copertina del libro e infine fate click su Scarica PDF



----------

[1] Bureau International des Poids et Mesures. The International System of Units (SI). URL consultato il 3/10/2020: https://bit.ly/30tZOiq

[2] Bureau International des Poids et Mesures. SI Brochure. URL consultato il 3/10/2020: https://bit.ly/3le9aXR


giovedì 13 agosto 2020

Tabulare una serie di test di normalità (gaussianità)

Quando con R si esegue una serie di test di normalità (gaussianità) su una variabile, può essere fastidioso consultare e confrontare tra loro risultati che nella Console di R sono riportati separatamente e lontani l'uno dall'altro. Personalmente trovo che gli stessi risultati compattati in una tabella e incolonnati siano molto meglio fruibili. Ma non solo. I valori di probabilità p incolonnati sono poi ancor meglio confrontabili tra loro se riportati in formato fisso anziché in formato esponenziale.

Vediamo quindi come incolonnare e riportare in formato fisso i risultati dei più comuni test di gaussianità con lo script che segue. Accertatevi di avere installati i pacchetti moments e nortest. Altrimenti dovete scaricarli e installarli dal CRAN. Accertatevi inoltre di avere installato il pacchetto DAAG che contiene i dati impiegati nello script, o in alternativa procedete come indicato nel post Il set di dati ais.

Copiate lo script, incollatelo nella Console di R e premete ↵ Invio.

# TABULARE UNA SERIE DI TEST DI NORMALITA' (GAUSSIANITA')
#
library(DAAG) # carica il pacchetto DAAG incluso il set di dati ais
mydata <- ais[,c(5)] # salva in mydata la colonna 5 con la variabile ferritina
#
# asimmetria, curtosi e quattro test di gaussianità
#
library(moments) # carica il pacchetto
agostino.test(mydata) # test di D'Agostino per il coefficiente di asimmetria
anscombe.test(mydata) # test di Anscombe-Glynn per il coefficiente di curtosi
library(nortest) # carica il pacchetto
ad.test(mydata) # test di Anderson-Darling per la gaussianità
cvm.test(mydata) # test di Cramer-von Mises per la gaussianità
pearson.test(mydata) # test chi-quadrato di Pearson per la gaussianità
sf.test(mydata) # test di Shapiro-Francia per la gaussianità
#
# sintetizza in una tabella i test con i risultati e i valori di p
#
stat <- c(names(agostino.test(mydata)$statistic[2]), names(anscombe.test(mydata)$statistic[2]), names(ad.test(mydata)$statistic), names(cvm.test(mydata)$statistic), names(pearson.test(mydata)$statistic), names(sf.test(mydata)$statistic)) # array con le denominazioni delle statistiche calcolate
ris <- c(agostino.test(mydata)$statistic[2], anscombe.test(mydata)$statistic[2], ad.test(mydata)$statistic, cvm.test(mydata)$statistic, pearson.test(mydata)$statistic, sf.test(mydata)$statistic) # array con i risultati delle statistiche calcolate
pval <- c(agostino.test(mydata)$p.value, anscombe.test(mydata)$p.value, ad.test(mydata)$p.value, cvm.test(mydata)$p.value, pearson.test(mydata)$p.value, sf.test(mydata)$p.value) # array con i valori di p
mydataset <- data.frame(stat, ris, pval) # combina gli array in una tabella
rownames(mydataset) <- c(agostino.test(mydata)$method, anscombe.test(mydata)$method, ad.test(mydata)$method, cvm.test(mydata)$method, pearson.test(mydata)$method, sf.test(mydata)$method) # aggiunge i nomi delle righe
colnames(mydataset) <- c("Statistica", "Risultato", "Valore p") # aggiunge i nomi delle colonne
mydataset # mostra la tabella
options(scipen=999) # esprime i numeri in formato fisso
mydataset # mostra nuovamente la tabella
options(scipen=0) # ripristina la notazione scientifica/esponenziale
#

Il test di asimmetria di D'Agostino agostino.test() valuta quanto e come la simmetria della distribuzione campionaria (quella effettivamente osservata) si discosta da quella della distribuzione gaussiana teorica, che è per definizione perfettamente simmetrica. Il test di curtosi di Anscombe-Glynn anscombe.test() valuta se la distribuzione campionaria è troppo appiattita (bassa e larga) o troppo appuntita (alta e stretta) rispetto alla distribuzione gaussiana teorica, in ciascun punto della quale vale un preciso rapporto tra distanza dal centro della distribuzione e altezza della curva.


Mentre i due test precedenti valutano separatamente asimmetria e curtosi, gli altri quattro test qui impiegati, il test di Anderson-Darling ad.test(), il test di Cramer-von Mises cvm.test(), il test chi-quadrato di Pearson pearson.test() e il test di Shapiro-Francia sf.test(), sono test globali di gaussianità (forniscono una valutazione globale del grado di scostamento della distribuzione osservata dalla distribuzione gaussiana teorica, ma non del tipo di scostamento).

Dopo avere calcolato e riportato separatamente i risultati dei sei test, viene generata la tabella che mostra per ciascun test la denominazione, il simbolo della statistica calcolata, il risultato numerico di detta statistica e il corrispondente valore di probabilità p procedendo in questo modo:
→ per ciascun test viene riportato nell'array (o se preferite vettore) stat il simbolo della statistica calcolata (names());
→ per ciascun test viene riportato nell'array ris il risultato numerico della statistica calcolata ($statistic);
→ per ciascun test viene riportato nell'array pval il valore di probabilità p del risultato numerico ($p.value);
→ mediante la funzione data.frame() gli array statris e pval sono combinati nella tabella mydataset;
 mediante la funzione rownames() a ciascuna riga della tabella mydataset viene assegnata la denominazione del test corrispondente ($method);
→ mediante la funzione colnames() sono assegnati i nomi alle colonne della tabella mydataset che contengono, nell'ordine, il simbolo stat della statistica (Statistica), il risultato ris della statistica (Risultato) e il valore pval di probabilità p (Valore p) [1].

La tabella viene quindi mostrata nella Console di R prima con i valori numerici espressi in notazione scientifica

                                  Statistica  Risultato     Valore p
D'Agostino skewness test                   z  6.1376120 8.377114e-10
Anscombe-Glynn kurtosis test               z  2.9448982 3.230609e-03
Anderson-Darling normality test            A  6.0970351 4.903750e-15
Cramer-von Mises normality test            W  0.9447263 2.495032e-09
Pearson chi-square normality test          P 63.7722772 2.530969e-08
Shapiro-Francia normality test             W  0.8913765 1.251172e-09

e poi con i valori numerici espressi in notazione fissa mediante options(scipen=999)

                                  Statistica  Risultato               Valore p
D'Agostino skewness test                   z  6.1376120 0.00000000083771142715
Anscombe-Glynn kurtosis test               z  2.9448982 0.00323060945215406870
Anderson-Darling normality test            A  6.0970351 0.00000000000000490375
Cramer-von Mises normality test            W  0.9447263 0.00000000249503195167
Pearson chi-square normality test          P 63.7722772 0.00000002530968668914
Shapiro-Francia normality test             W  0.8913765 0.00000000125117173937

L'incolonnamento e il formato fisso rendono sicuramente più chiara la sintesi e la valutazione comparativa dei risultati numerici. La probabilità p è la probabilità di osservare per caso il risultato numerico della statistica (z, A, WP secondo i casi) che misura lo scostamento della distribuzione osservata dalla distribuzione gaussiana teorica. Se tale probabilità è sufficientemente piccola, si conclude che il risultato ottenuto non è imputabile al caso e che pertanto la distribuzione dei dati si discosta significativamente dalla distribuzione gaussiana. Tutti e sei i test confermano che la ferritina non segue una distribuzione gaussiana: infatti abbiamo un valore p < 0.05 - cioè un p inferiore al valore del 5% tradizionalmente assunto come soglia per la significatività - in tutti i casi, e addirittura di molti ordini di grandezza inferiore al 5% in cinque casi su sei. Potete avere una conferma visiva di queste conclusioni con le rappresentazioni grafiche, sempre altamente consigliate come complemento all'analisi statistica, che potete realizzare con lo script riportato nel post Analizzare graficamente la distribuzione di una variabile

Come al solito lo script è realizzato in modo da essere facilmente riutilizzabile, essendo sufficiente a questo scopo:
→ sostituire la prima riga di codice con il codice per importare i vostri dati [2];
sostituire nella seconda riga di codice ais[,c(5)] con il nome della variabile da analizzare contenuta nei dati che avete importato.


----------

[1] Potete al bisogno approfondire la documentazione delle funzioni qui impiegate digitando help(nomedellafunzione) nella Console di R.

[2] Per una guida rapida all'importazione dei dati potete consultare i link: