martedì 15 aprile 2025

Gradi centigradi o gradi Celsius?

Se è vero che la statistica è la tecnica che consente di fornire un supporto scientifico alle evidenze fornite dalle misure, ci sono dal punto di vista metodologico, nelle misure da sottoporre ad analisi statistica, quattro aspetti sull'importanza dei quali non mi stancherò mai di richiamare l'attenzione [1], uno dei quali è:
→ l'utilizzo di un sistema di unità di misura razionale, documentato e condiviso quale è il Sistema internazionale di unità (SI) –  adottato per legge anche in Italia – applicandone integralmente e senza eccezioni le indicazioni.

Per l'appunto: il Sistema Internazionale di unità (SI) è stato adottato per legge in Italia nel 1982, e le successive modifiche sono state adottate per legge nel 2001, nel 2009 e nel 2020 [2]. 

Ma perché ricordare una cosa che dovrebbe essere arcinota?

Perché un bel giorno ricevo una mail che contiene, tra le anteprime giornalistiche del quotidiano al quale sono abbonato, questa immagine e il suo commento.


Faccio una rapida ricerca su Google e trovo che se le espressioni "grado celsius" e "gradi celsius" sono citate 737 000 volte, le espressioni 
"grado centigrado" e "gradi centigradi" sono citate ben 268 000 volte: insomma, più di una volta su quattro.

Ma il Sistema Internazionale di unità (SI) non prevede il grado centigrado!

La brochure ufficiale che illustra il SI [3] riporta tra le molte altre cose le sette unità di base del SI, che includono la temperatura termodinamica espressa in kelvin (K):


(a) I simboli delle grandezze sono generalmente singole lettere dell'alfabeto Latino o Greco, sono in carattere corsivo (in francese "italique"; in inglese "italic") e sono raccomandazioni.

(b) I simboli delle unità sono in carattere tondo (in francese "romain"; in inglese "roman") e sono mandatori.

(c) Dopo i simboli non si deve mettere il punto (kg e non kg. ovvero mol e non mol. e così via): si tratta appunto di simboli, e non di abbreviazioni.

Sempre come riportato nella brochure, dalle unità di base del SI si ricavano le ventidue unità SI con nomi e simboli speciali che seguono e che includono la temperatura Celsius espressa in gradi Celsius (°C):

Il valore numerico di una temperatura Celsius (t) espressa in gradi Celsius (°C) è collegato al valore numerico di una temperatura termodinamica (T) espressa in kelvin (K) dalla relazione

t/°C = T/K - 273.15  [4]


Da notare che in questo modo il valore numerico di una differenza (o intervallo) di temperatura è lo stesso quando espresso in kelvin o in gradi Celsius: se una temperatura aumenta (ad esempio) di 10 kelvin, aumenta anche esattamente di 10 gradi Celsius. Mentre posso dire che questa mattina nel giardino di casa il mio termometro segnava "una temperatura di 0 gradi [Celsius]" piuttosto che "una temperatura di 273.15 kelvin". 

Come riportato anche nella SI Brochure [3] la decisione di adottare il Sistema Internazionale di unità (SI) è stata presa durante la 9ª CGPM (la Conferenza Generale dei Pesi e Misure ovvero il "parlamento" nel quale i rappresentanti nazionali discutono e adottano le decisioni in merito alle convenzioni in campo metrologico) che si è tenuta nel 1948. In quella occasione si è anche deciso di adottare – in luogo del fino ad allora denominato "grado centesimale" o "grado centigrado" – il "grado Celsius", in onore dello svedese Anders Celsius che nel 1742 aveva pubblicato, negli Atti della Accademia Reale Svedese di Scienze, la proposta di adottare per la misura della temperatura una scala centesimale con due punti fissi, il punto 0 alla temperatura di ebollizione dell'acqua e il punto 100 alla temperatura di congelamento dell'acqua [5]. 

Fu il fisico francese Jean-Pierre Christin nel 1743 a proporre un termometro a mercurio che scambiava tra loro i valori assegnati ai due punti fissi ponendo a 0 gradi la temperatura di congelamento e a 100 gradi la temperatura di ebollizione dell'acqua come descritto in questo documento [6] a p. 250: "En juillet 1743, il fait connaître au public, par la voie des journaux (Mercure de France, etc., etc.), son thermomètre centigrade à mercure, sous le nom de Thermomètre de Lyon, divisé selon la mesure de la dilatation du mercure..." e alle pp. 259-260: "... le zéro vrai du thermomètre de Celsius marquait l'eau bouillante, tandis que le 100 ͤ degré correspondait à la congélation, ce qui est précisément l'inverse de la graduation lyonnaise".

La stessa scala l'adottò, probabilmente senza sapere del lavoro di Christin, Carlo Linneo tre anni dopo il lavoro del suo connazionale Celsius. Infatti nel suo Hortus upsaliensis del 1745 a p. 23 Linneo riporta in una nota: "Thermometrum nostrum est 0 in puncto congelationis et numerat 100 ad gradus aquæ coquentis[7].

Nella prima metà del '700 la misura della temperatura era considerata dagli scienziati un obiettivo molto importante, se in precedenza:
 già nel 1724 il tedesco Daniel Gabriel Fahrenheit, ispirandosi a studi ancora precedenti del danese Ole Christensen Rømer, aveva proposto l'impiego del mercurio e di una scala delle temperature [8] che, dopo varie modifiche, è diventata l'attuale scala Fahrenheit (il grado Fahrenheit, con il simbolo °F, è ammesso per l'uso corrente negli USA, nei quali comunque si impiegano in campo scientifico le unità del SI al quale gli USA aderiscono), che fissa a 32 gradi il punto di congelamento dell'acqua e a 212 gradi il punto di ebollizione, con un intervallo di 180 gradi tra le due temperature;
 nel 1732 il francese René-Antoine Ferchault de Réaumur aveva proposto un termometro ad alcool con un intervallo di 80 gradi: "Il s'est déterminé à faire remplir les Thermometres d'un Esprit de Vin, dont le volume étant de 1000 parties, lorsqu'il a pris le froid de l'eau qui commence à se geler, devient 1080, lorsqu'il a pris le plus grand degré de chaleur que l'eau puisse lui donner sans le faire boüillir[9], in un lavoro cui si era ispirato Christin.

Infine non dobbiamo dimenticare i contributi di scienziati italiani in quelli che erano stati i primordi nella misura delle temperature, con:
 il termoscopio, lo strumento messo a punto da Galileo Galilei nel 1597 che a livello sostanzialmente qualitativo "evidenziava le variazioni della densità dell'aria prodotte dalle variazioni di temperatura" [10];
 vari tipi di termometro tra cui il termometro a fiala [11] – descritto nel 1666 nei verbali dell'Accademia del Cimento [12] come "... un Termometro ma piu pigro, e infingardo di tutti gli altri. Poichè dove quegli per ogni poco, che l'aria ſi ſtemperi veggonſi ſubito alterare, queſt'altro non è tanto veloce, ed a muoverlo vi vuol'altro che minime, ed inſenſibili differenze. Nulladimeno perchè di queſti ancora, n'è andati in diuverſe parti dentro, e fuori d'Italia; ſi dira brevemente in queſto luogo della loro fabbrica…" – che appartiene alla fase della misura semiquantitativa della temperatura, effettuata in questo caso mediante ampolle colorate che si muovono su e giù al cambiare della densità (che è funzione della temperatura) del mezzo in cui sono immerse. Nell'immagine a destra una versione attuale, impropriamente denominata "termometro galileiano", del termometro a fiala indicato come V nella tavola di sinistra, tratta da [12]: i cinque termometri da I a V illustrati erano riempiti con "il ſottiliſsimo ſpirito del vino, o acquarzente". Come VI nella tavola è indicato invece uno strumento che serviva "per riconoscere le differenze dell'umido nell'aria".


Conclusione: il mio sogno nel cassetto, uno dei tanti? Non vedere mai più temperature riportate in gradi centigradi. Per favore (e per razionalità scientifica, oltre che per una norma vigente) o parliamo di kelvin (K), ma questo avviene in ambito scientifico, o parliamo in alternativa di gradi Celsius (°C), cioè nei termini corretti delle unità di misura della temperatura nelle quali dobbiamo esprimerci [13]. E in ogni caso chiediamo che i dati da elaborare statisticamente siano sempre espressi con le grandezze, le denominazioni, le unità di misura, i simboli, i multipli e i sottomultipli del SI, indirizzando l'interlocutore al bisogno anche alle JCGM Publications: Guides in Metrology [14].


----------

[2] Il Sistema Internazionale di unità (SI) diviene legale in Italia nel 1982, le successive modifiche sono recepite nel 2001, nel 2009 e nel 2020, questa è la normativa aggiornata a inizio 2024, che include la correzione riportata a livello comunitario nel 1984:
- DECRETO DEL PRESIDENTE DELLA REPUBBLICA 12 agosto 1982, n. 802. Attuazione della direttiva (CEE) n. 80/181 relativa alle unita' di misura. GU Serie Generale n.302 del 03-11-1982 - Suppl. Ordinario.
https://www.gazzettaufficiale.it/eli/id/1982/11/03/082U0802/sg
- DIRETTIVA DEL CONSIGLIO del 18 dicembre 1984 che modifica la direttiva 80/181/CEE per il ravvicinamento delle legislazioni degli Stati membri relative alle unità di misura.
https://eur-lex.europa.eu/legal-content/IT/TXT/PDF/?uri=CELEX:31985L0001
- DECRETO 29 gennaio 2001. Attuazione della direttiva 1999/103/CE che modifica la direttiva 80/181/CEE sul riavvicinamento delle legislazioni degli Stati membri relative alle unita' di misura. GU Serie Generale n.27 del 02-02-2001 
https://www.gazzettaufficiale.it/eli/id/2001/02/02/001A1152/sg
- DECRETO 29 ottobre 2009. Attuazione della direttiva 2009/3/CE del Parlamento europeo e del Consiglio dell'11 marzo 2009 che modifica la direttiva 80/181/CEE del Consiglio sul riavvicinamento delle legislazioni degli Stati membri riguardo alle unita' di misura. (09A13580). GU Serie Generale n.273 del 23-11-2009 
https://www.gazzettaufficiale.it/eli/id/2009/11/23/09A13580/sg
- DECRETO 7 aprile 2020. Attuazione della direttiva (UE) 2019/1258 della Commissione del 23 luglio 2019 che modifica, ai fini dell'adattamento al progresso tecnico, l'allegato della direttiva 80/181/CEE del Consiglio per quanto riguarda le definizioni delle unita' SI di base.
https://www.gazzettaufficiale.it/eli/id/2020/05/09/20A02529/sg

[3] SI Brochure: The International System of Units (SI)
https://www.bipm.org/en/publications/si-brochure

[4] La spiegazione della notazione impiegata è riportata nella SI Brochure [3] e a pag. 52 del mio ebook su Grandezze e unità di misura che può essere scaricato a questi link:
https://www.academia.edu/41041923/
https://play.google.com/books/reader?id=GciVDwAAQBAJ
https://www.bayes.it/SI.pdf

[5] Celsius, Anders (1742). Observationer om twänne beständiga grader på en thermometer. Kungliga Svenska Vetenskapsakademiens Handlingar (3): 171–180.
https://archive.org/stream/kungligasvenskav1317kung

[6] SUR L'INVENTION DU THERMOMÈTRE CENTIGRADE A MERCURE, Faite à Lyon par M. CHRISTIN. NOTICE LUE A LA SOCIÉTÉ D'AGRICULTURE DE LYON, Dans la séance du 4 juillet 1845. In: ANNALES DES SCIENCES PHYSIQUES ET NATURELLES, D'AGRICULTURE ET D'INDUSTRIE, PUBLIÉES PAR La Société royale d'Agriculture, etc., DE LYON. TOME VIII. 1845.
https://play.google.com/books/reader?id=o4g9AQAAMAAJ

[7] Hortus upsaliensis, 1745.
https://ia800503.us.archive.org/16/items/naucler-1745/Naucler1745.pdf

[8] VIII. Experimenta & observationes de congelatione aquæ in vacuo factæ a D. G. Fahrenheit, R. S. S. In: Philosophical Transactions of the Royal Society of London, Volume 33, Issue 382. Published: 30 April 1724.
https://doi.org/10.1098/rstl.1724.0016

[9] Explication des principes établis par M. de Reaumur, pour la construction des thermometres dont les degrés soient comparables. 1732.
https://gallica.bnf.fr/ark:/12148/bpt6k6535672b/

[10] Museo Galileo. Termoscopio.
https://catalogo.museogalileo.it/oggetto/Termoscopio.html

[11] Museo Galileo. Termometri a fiala.
https://catalogo.museogalileo.it/oggetto/TermometriFiala.html

[12] DI NATVRALI ESPERIENZE FATTE NELL'ACCADEMIA DEL CIMENTO SOTTO LA PROTEZIONE DEL SERENISSIMO PRINCIPE LEOPOLDO DI TOSCANA E DESCRITTE DAL SEGRETARIO DI ESSA ACCADEMIA. IN FIRENZE. MDCLXVI. 
https://play.google.com/books/reader?id=BcCpGiXkRKsC

[13] Notare tra l'altro che, poiché la legge non ammette ignoranza, un atto legale che riporta una temperatura espressa in "gradi centigradi" potrebbe essere impugnato.

[14] Vedere i documenti:
 GUM: Guide to the Expression of Uncertainty in Measurement
 VIM: International Vocabulary of Metrology
https://www.bipm.org/en/committees/jc/jcgm/publications

sabato 12 aprile 2025

Grafici a barre (barplot) con ggplot

grafici a barre (bar plot o barplot) si possono realizzare impiegando le funzioni base di R [1]. Tuttavia con il pacchetto ggplot2 si possono ottenere risultati molto interessanti, qui illustrati con tre script che si aggiungono ad altri già riportati [2] e che, quando si è agli inizi, possono aiutare a familiarizzare con le funzioni di questo pacchetto.

Come trovate riportato nel manuale di riferimento del pacchetto [3] "... Esistono due tipi di grafici a barre: geom_bar() e geom_col() ... geom_bar() rende l'altezza della barra proporzionale al numero di casi in ogni gruppo ... Se volete che le altezze delle barre rappresentino i valori nei dati, usate geom_col() al suo posto".

Oltre al pacchetto ggplot2 [4] dovete accertarvi di avere installato – o dovete scaricare anche – il pacchetto DAAG [5] che contiene il set di dati ais impiegati nell'esempio, il pacchetto RColorBrewer che contiene una serie di palette (raccolte di colori) aggiuntive e il pacchetto gridExtra che consente di combinare i grafici in una sola figura.

Vediamo ora la funzione geom_col() che realizza grafici a barre nei quali le altezze delle barre rappresentano i valori dei dati

Copiate e incollate nella Console di R questo script e premete ↵ Invio.

# BARPLOT con ggplot 
# barplot semplici
#
library(ggplot2) # carica il pacchetto per la grafica
library(RColorBrewer) # carica il pacchetto con le palette aggiuntive
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
# genera la tabella con i dati da rappresentare
mydata <- data.frame(loc=c("Milano", "Catania", "Roma"), temp=c(18.3, 26.8, 21.2))
#
# barplot di base
plot1 <- ggplot(data=mydata, aes(x=loc, y=temp)) + geom_col()
#
# scambia tra loro gli assi
plot2 <- ggplot(data=mydata, aes(x=loc, y=temp, fill=as.factor(temp))) + geom_col(width=0.6) + ylim(0, 30) + labs(x="Località", y="Temperatura in gradi Celsius") + theme(legend.position="bottom") + scale_fill_discrete(name="°C") + coord_flip()
#
# riporta i valori numerici in testa alle barre
plot3 <- ggplot(data=mydata, aes(x=loc, y=temp)) + geom_col(width=0.6, fill="steelblue3") + ylim(0, 30) + labs(x="Località", y="Temperatura in gradi Celsius") + scale_x_discrete(limits=c("Milano", "Roma", "Catania")) + geom_text(aes(label=temp), vjust=-0.6, color="black", size=3.2)
#
# applica alle barre un gradiente di colori
plot4 <- ggplot(data=mydata, aes(x=loc, y=temp, fill=as.factor(temp))) + geom_col(width=0.6) + ylim(0, 30) + labs(x="Località", y="Temperatura in gradi Celsius") + scale_x_discrete(limits=c("Milano", "Roma", "Catania")) + theme_classic() + scale_fill_brewer(palette="Blues") + labs(fill="°C")
#
# 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 i dati impiegati come esempio (mydata):

      loc temp
1  Milano 18.3
2 Catania 26.8
3    Roma 21.2

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 (mydata);
 come secondo argomento la funzione aes() che specifica di riportare in ascisse (x=) la variabile (fattore) loc che indica la località e in ordinate (y=) la variabile (numerica) temp che riporta la temperatura rilevata espressa in gradi Celsius (°C). Alla funzione ggplot() viene quindi collegata con il segno più [+la funzione geom_col() che realizza come anticipato il grafico a barre nel quale le altezze delle barre rappresentano i valori dei dati.

Questa è la struttura base che rimane identica in tutti e quattro i grafici realizzati, che si differenziano tra loro per le personalizzazioni grafiche via via introdotte.

Il secondo grafico (plot2) aggiunge:
→ la colorazione automatica delle barre con un colore diverso per ogni località (fill=loc);
→ la riduzione dell'ampiezza della barre con width=0.6;
→ la personalizzazione della scala delle ordinate che ora va da 0 a 30;
→ la funzione labs() che specifica le etichette delle ascisse e delle ordinate;
→ la funzione theme() che specifica la posizione in basso ("bottom") per la legenda;
→ il titolo °C della legenda con la funzione scale_fill_discrete();
→ la funzione coord_flip() che scambia tra di loro la posizione degli assi.

Nel terzo grafico (plot3):
→ con fill="steelblue3" viene specificato manualmente il colore delle barre;
→ con scale_x_discrete() viene specificato manualmente l'ordine delle barre;
→ con geom_text() in testa a ciascuna barra viene riportata la temperatura corripondente (temp) specificando posizione (vjust), colore (color) e dimensione (size) dei caratteri.

Il quarto grafico (plot4) ricalca il terzo grafico e in aggiunta:
→ con theme_classic() ripristina la struttura classica impiegata nei grafici;
→ con scale_fill_brewer() applica il gradiente di colori della palette Blues;
→ con labs() riporta nella legenda il titolo °C.

Infine con la funzione grid.arrange() i quattro grafici sono combinati in un'unica figura.


Per vedere come lavorare su dati che contengono un fattore di classificazione copiate e incollate nella Console di R questo secondo script e premete ↵ Invio.

# BARPLOT con ggplot
# barplot con un fattore
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
library(RColorBrewer) # carica il pacchetto con le palette aggiuntive
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
# calcola sui dati della tabella ais la mediana di hg per sport 
hgb <- aggregate(hg~sport, data=ais, median) 
hgb # mostra la tabella con i dati da rappresentare
#
# barplot di base
plot1 <- ggplot(data=hgb, aes(x=sport, y=hg)) + geom_col(fill="steelblue3") + ylim(0, 20) + theme(axis.text.x=element_text(angle=90, hjust=1)) 
#
# scambia tra loro gli assi
plot2 <- ggplot(data=hgb, aes(x=sport, y=hg)) + geom_col(width=0.8, fill="steelblue3") + ylim(0, 20) + coord_flip()
#
# riporta i valori numerici all'interno delle barre
plot3 <- ggplot(data=hgb, aes(x=reorder(sport, -hg), y=hg)) + geom_col(width=0.8, fill="steelblue3") + ylim(0, 20) + geom_text(aes(label=hg), vjust=1.6, color="white", size=2.8) + theme(axis.text.x=element_text(angle=90, hjust=1)) + theme(legend.position="none") + labs(title="Mediana dell'emoglobina \n per sport", x="Sport praticato", y="Emoglobina in g/dL")
#
# applica alle barre un gradiente di colori
mycolors <- colorRampPalette(brewer.pal(9, "Blues"))(40)[11:20] # porta da 9 a 40 i colori della palette e seleziona i 10 colori da 11 a 20
plot4 <- ggplot(data=hgb, aes(x=reorder(sport, hg), y=hg, fill=as.factor(hg))) + geom_col(width=0.8) + theme_classic() + ylim(0, 20) + geom_text(aes(label=hg), vjust=-0.6, color="black", size=3.2) + theme(axis.text.x=element_text(angle=90, hjust=1)) + theme(legend.position="none") + labs(title="Mediana dell'emoglobina \n per sport", x="Sport praticato", y="Emoglobina in g/dL") + theme(plot.title=element_text(hjust=0.5)) + scale_fill_manual(values=mycolors)
#
# combina i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2) 
#

Innanzitutto sui dati della tabella ais contenuta nel pacchetto DAAG è calcolata la mediana (median) dell'emoglobina per ciascuno sport (hg~sport), salvandola nella nuova tabella hgb che viene mostrata e che contiene ora i dati da rappresentare:

> hgb # mostra la tabella con i dati da rappresentare
     sport   hg
1   B_Ball 14.0
2    Field 15.5
3      Gym 13.7
4  Netball 12.7
5      Row 14.7
6     Swim 15.1
7   T_400m 14.8
8  T_Sprnt 15.2
9   Tennis 14.3
10  W_Polo 15.6

Nel primo grafico (plot1):
→ sono impiegati i dati della tabella hg riportando in ascisse sport e in ordinate la mediana hg dell'emoglobina;
→ le barre sono colorate tutte con lo stesso colore, specificato in fill;
→ con la funzione ylim() viene dimensionata la scala delle ordinate da 0 a 20;
→ con theme() le etichette dell'asse delle x sono riportate in verticale (angle=90).

Il secondo grafico (plot2) è identico al precedente a parte il fatto che le barre sono ridotte di ampiezza (width=0.8) e gli assi sono scambiati tra loro con coord_flip() per porre le barre in orizzontale.

Il terzo grafico (plot3) riprende nuovamente il primo con alcune aggiunte e modifiche:
→ le barre sono ordinate ponendo la mediana dell'emoglobina in ordine decrescente (-hg);
→ con geom_text() sono riportate all'interno delle barre (vjust=1.6) in colore chiaro (white), rimpiccolendo lievemente i caratteri (size=2.8), le etichette con i valori (label=hg) della mediana dell'emoglobina;
→ con theme() le etichette dell'asse delle x sono riportate in verticale (angle=90);
→ viene esclusa la rappresentazione della legenda ("none");
→ con labs() sono aggiunti il titolo e le etichette degli assi.

Il quarto grafico (plot4) ripresenta il terzo grafico con poche aggiunte e modifiche:
→ innanzitutto sono portati da 9 a 40 i colori della palette, sono selezionati i 10 colori da 11 a 20, e questi sono memorizzati nell'oggetto mycolors;
→ sono riportati colori diversi per ciascun valore dell'emoglobina con as.factor(hg);
→ viene tolto lo sfondo con theme_classic();
→ le etichette con i valori della mediana dell'emoglobina sono portate all'esterno delle barre (vjust=-0.6) aumentando lievemente la dimensione dei caratteri (size=3.2);
→ con hjust=0.5 il titolo viene centrato;
→ le barre sono riportate nel gradiente di colori memorizzati in mycolors.

Questi sono i quattro grafici risultanti.



Vediamo ora cosa accade quando si desidera realizzare i grafici a barre a partire da una tabella che contiene due fattorinei quali come nei due casi precedenti le altezze delle barre rappresentano i valori dei dati e quindi è necessario impiegare la funzione geom_col().

Copiate e incollate nella Console di R questo script e premete ↵ Invio.

# BARPLOT con ggplot 
# barplot con due fattori
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
library(plotrix) # carica il pacchetto per il calcolo dell'errore standard
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
# aggrega i dati calcolando media ed errore standard per sport e per sesso
hg <- aggregate(hg~sport+sex, data=ais, FUN=function(x) c(mean=mean(x), se=std.error(x))) 
hg # mostra i dati da rappresentare
media <- hg$hg[,1] # vettore contenente la media
es <- hg$hg[,2] # vettore contenente l'errore standard
#
# grafico a barre impilate per sport e sesso
plot1 <- ggplot(data=hg, aes(x=sport, y=media, fill=sex)) + geom_col() + theme(axis.text.x=element_text(angle=90, hjust=1)) + ylim(0, 31)
#
# grafico a barre affiancate per sport e sesso
plot2 <- ggplot(data=hg, aes(x=sport, y=media, fill=sex)) + geom_col(position=position_dodge()) + theme(axis.text.x=element_text(angle=90, hjust=1)) + ylim(0, 31)
#
plot3 <- ggplot(data=hg, aes(x=sport, y=media, fill=sex)) + geom_col(position=position_dodge()) + theme(axis.text.x=element_text(angle=90, hjust=1)) + ylim(0, 20) + geom_errorbar(aes(ymin=media-1.96*es, ymax=media+1.96*es), width=0.2, position=position_dodge(0.9)) + labs(title="Media dell'emoglobina ± 1.96 es") 
#
plot4 <- ggplot(data=hg, aes(x=sport, y=media, fill=sex)) + geom_point(aes(fill=sex), shape=21, size=3, position=position_dodge(0.9)) + theme_classic() + theme(axis.text.x=element_text(angle=90, hjust=1)) + ylim(0, 20) + geom_errorbar(aes(ymin=media-1.96*es, ymax=media+1.96*es), width=0.2, position=position_dodge(0.9)) + labs(title="Media dell'emoglobina ± 1.96 es", x="Sport praticato", y="Emoglobina in g/dL") + scale_fill_discrete(name = "Sesso", labels = c("Donne", "Uomini"))
#
# combina i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2) 
#

In questo caso dai dati della tabella ais contenuta nel pacchetto DAAG riportiamo la variabile emoglobina suddivisa per sport e per sesso (hg~sport+sex) e ne calcoliamo la media (mean) e l'errore standard (std.error) – quest'ultima funzione richiede il pacchetto plotrix – e questa è la tabella risultante della quale vogliamo rappresentare i grafici a barre:

> hg # mostra i dati da rappresentare
     sport sex    hg.mean      hg.se
1   B_Ball   f 13.1307692  0.2434750
2    Field   f 14.6285714  0.2579353
3      Gym   f 13.6000000  0.4301163
4  Netball   f 12.8173913  0.1182301
5      Row   f 14.0318182  0.1576871
6     Swim   f 13.5666667  0.1943651
7   T_400m   f 13.7727273  0.3122036
8  T_Sprnt   f 14.1750000  0.2780138
9   Tennis   f 13.5285714  0.4144499
10  B_Ball   m 15.1416667  0.2661335
11   Field   m 16.0250000  0.2322893
12     Row   m 15.3866667  0.1835799
13    Swim   m 15.5076923  0.1816807
14  T_400m   m 15.3055556  0.1941080
15 T_Sprnt   m 16.1909091  0.4503442
16  Tennis   m 15.6500000  0.7410578
17  W_Polo   m 15.5176471  0.1741017

Nel primo grafico (plot1) è riportata la struttura base che impieghiamo:
→ sono riportate le barre che rappresentano la media (media) dell'emoglobina con un colore separato per ciascun sesso (fill=sex);
→ con theme() le etichette dell'asse delle x sono riportate in verticale (angle=90); 
→ con la funzione ylim() viene dimensionata la scala delle ordinate da 0 a 31;
→ per tutti gli altri parametri grafici sono lasciati i valori di default per cui abbiamo un grafico a barre impilate che include automaticamente anche una legenda.

Il secondo grafico (plot2) differisce dal precedente solamente per il fatto che, con position=position_dodge(), realizziamo un grafico a barre affiancate.

Nel terzo grafico (plot3):
→ per una miglior visualizzazione viene dimensionata la scala delle ordinate da 0 a 20;
→ con geom_errorbar() si riportano in testa a ciascuna barra, la cui altezza è la media dell'emoglobina, i limiti ±1.96 volte l'errore standard (es) cioè i limiti di confidenza al 95% della media;
→ si aggiunge un titolo.

Il quarto grafico (plot4) ripresenta il precedente ma:
→ sostituisce le barre con un circolo (shape=21) di diametro size=3 posizionato in corrispondenza della media;
→ con theme_classic() toglie lo sfondo;
→ aggiunge agli assi le etichette con una descrizione delle grandezze rappresentate;
→ con scale_fill_discrete() personalizza la legenda.

Questi sono i quattro grafici così realizzati.


Due brevi considerazioni, basate sull'assunto che i grafici possono essere impiegati per fornire una rappresentazione sintetica dei dati, ma che questa non deve mai essere fuorviante:
→ per consentire un confronto dei valori in relazione a un fattore (qui il sesso) è necessario impiegare barre affiancate (in alto a destra), le barre impilate (in alto a sinistra) sono da evitare;
→ è da evitare la rappresentazione delle medie sotto forma di barre (in basso a sinistra), in quanto queste danno l'idea di un "continuum" di valori che parte da 0, modi adeguati possono essere (i) la rappresentazione puntiforme qui impiegata (in basso a  destra) o in alternativa anche (ii) un grafico a scatola con i baffi [6].  

Vediamo ora la funzione geom_bar() che realizza grafici a barre nei quali le altezze delle barre rappresentano i conteggi dei dati all'interno dei casi di volta in volta specificati. La facciamo con tre esempi molto semplici.

Nel primo esempio:
→ le barre sono riportate in colore grigio con fill="grey";
→ con theme() le etichette dell'asse delle x sono riportate in verticale (angle=90);
→ viene conteggiato il totale dei casi (numero di atleti) per ciascuno sport.

# BARPLOT con ggplot (barplot semplice)
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
#
# barplot di base
ggplot(data=ais, aes(x=sport)) + geom_bar(fill="grey") + theme(axis.text.x=element_text(angle=90, hjust=1)) 
#

Nel secondo con aes(fil=sex) si riportano per ciascuna barra colori differenziati in base alla variabile/fattore sesso (sex) quindi viene conteggiato il numero di casi (numero di atleti) per ciascun sesso, lasciando le barre sovrapposte.

# BARPLOT con ggplot 
# barplot sovrapposti, con un fattore
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
#
# barplot sovrapposti differenziati per sesso
ggplot(data=ais, aes(x=sport)) + geom_bar(aes(fill=sex)) + theme(axis.text.x=element_text(angle=90, hjust=1)) 
#

Nel terzo aggiungendo position=position_dodge() alla funzione geom_bar() le barre vengono affiancate.

# BARPLOT con ggplot 
# barplot affiancati, con un fattore
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
library(ggplot2) # carica il pacchetto per la grafica
#
# barplot affiancati differenziati per sesso
ggplot(data=ais, aes(x=sport)) + geom_bar(aes(fill=sex), position=position_dodge()) + theme(axis.text.x=element_text(angle=90, hjust=1)) 
#

I tre grafici ottenuti sono qui riportati affiancati, quello del primo script in alto a sinistra e quello dell'ultimo a destra.


Potete aggiungere ulteriori approfondimenti consultando gli altri post nei quali il pacchetto ggplot2 è stato impiegato [2] e al bisogno attraverso la sua documentazione ufficiale [4].

---------- 


[2] Fate click su ggplot2 nelle Parole chiave o digitate ggplot2 nella casella Cerca nel blog quindi fate click su Cerca.

[3] "There are two types of bar charts: geom_bar() and geom_col() [and] geom_bar() makes the height of the bar proportional to the number of cases in each group ... If you want the heights of the bars to represent values in the data, use geom_col() instead".

[4] Vedere la documentazione e il manuale di riferimento su:
https://cran.r-project.org/web/packages/ggplot2/index.html

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

[6] Fate click su grafici a scatola con i baffi nelle Parole chiave.