Archivio tag: ggplot2

Visualizzare la relazione fra due variabili likert

Lavorando nel campo della psicologia, spesso mi trovo ad avere a che fare con variabili che derivano da riposte a questionari fornite utilizzando scale di tipo Likert. Si tratta di variabili che possono assumere un numero molto limitato di modalità, comunemente da tre a cinque. Quando le categorie di riposta sono almeno cinque, spesso queste variabili vengono considerate come se fossero continue e di conseguenza vengono analizzate usando indicatori e modelli statistici pensati appunto per variabili continue.

Con questo post non voglio entrare nel merito della correttezza di queste scelte (condivisibili o meno, a seconda dei casi), ma concentrarmi sul modo di utilizzare al meglio gli strumenti statistici, principalmente i grafici.

Di seguito viene costruito il data frame likert che contiene due variabili: item1 e item2, che riportano le risposte (espresse su scala Likert a cinque punti) di sessanta ipotetiche persone a due ipotetiche domande di un ipotetico questionario.

likert <- data.frame(
    item1 = c(5,3,5,5,4,1,2,3,3,5,5,2,1,3,3,3,4,2,4,1,
              3,4,4,5,3,4,5,2,1,4,3,2,3,2,4,5,5,2,5,3,4,
              4,3,2,1,1,1,5,2,3,1,1,2,2,2,3,4,2,4,3),
    item2 = c(5,2,5,4,4,1,3,3,1,3,3,2,1,3,1,3,1,2,4,1,
              3,4,2,4,4,5,5,2,1,1,1,4,4,2,4,4,5,2,5,4,5,
              3,3,1,2,2,1,5,5,5,3,4,1,1,3,2,4,2,3,2)
)
&#91;/code&#93;

Per studiare la relazione tra due variabili di questo tipo, quello che comunemente viene fatto è calcolare l'indice di correlazione lineare. Possiamo usare l'indice di Pearson oppure l'indice di Spearman, basato sui ranghi.

Attraverso il comando <b>cor</b> di R possiamo calcolare entrambi gli indici; se non viene specificato nulla nell'argomento <i>method</i>, verrà calcolata la correlazione di Pearson:

[code language="R"]
> with(likert, cor(item1, item2))
[1] 0.5901713

Se invece vogliamo calcolare l’indice di Spearman, dobbiamo esplicitare questa richiesta nell’argomento method:

> with(likert, cor(item1, item2, method="spearman"))
[1] 0.5864863

Entrambi gli indici evidenziano un’ottima correlazione fra le due variabili (“ottima” almeno per gli standard in psicologia): si sfiora lo 0.6, che è un valore abbastanza elevato.

Quello che – ahimè – non fa quasi nessuno, è visualizzare la relazione tra le due variabili. I grafici hanno sempre tanto da raccontare e talvolta è proprio dalle visualizzazioni che emergono gli aspetti più interessanti. Proviamo quindi a creare uno scatterplot per visualizzare la relazione fra item1 e item2. Utilizziamo il comando plot, aumentando la dimensione dei punti sfruttando l’argomento cex:

with(likert, plot(item1, item2, cex=2))

Scatter-plot fra item1 e item2

Beh, che ve ne pare? Si tratta di una buona visualizzazione? Secondo me, no.

A vedere questo grafico a me sorgono molte perplessità. Abbiamo appena detto che la relazione lineare tra le due variabili è buona, ma dal grafico proprio non si direbbe: i punti sono sparpagliati un po’ ovunque e le due variabili sembrano tutto fuorché correlate.

Il problema di questo grafico è che le variabili possono assumere pochi valori (da 1 a 5), per cui moltissime risposte si sovrappongono. Ognuno di quei pallini in realtà ha una densità, perché su ognuno di essi si sovrappongono le risposte di più individui. Osservando bene l’immagine, infatti, possiamo notare che ci sono pallini il cui contorno è più scuro di altri; ebbene, nelle coordinate più scure si concentrano le risposte di più persone.

Il numero di osservazioni presente in ogni coordinata è un dato fondamentale per comprendere la relazione tra due variabili che assumono un numero ridotto di modalità, ma nell’immagine qui sopra questa informazione non è ben rappresentata.

La “densità” può essere calcolata semplicemente contando il numero di risposte che occorrono per ognuno degli incroci dei valori delle due variabili, ovvero costruendo una tabella di frequenza a doppia entrata:

> tab <- with(likert, table(item1, item2))
> tab
     item2
item1 1 2 3 4 5
    1 5 2 1 1 0
    2 3 6 2 1 1
    3 3 3 5 3 1
    4 2 1 2 5 2
    5 0 0 2 3 6

Osservando la tabella qui sopra possiamo notare come le frequenze maggiori siano collocate sulla diagonale, fenomeno che supporta la presenza di una relazione lineare e che giustifica valori di correlazione così elevati. Ma come fare per considerare questa informazione nel grafico?

Adesso vi proporrò due alternative; entrambe richiedono che la tabella di frequenza che abbiamo appena costruito venga convertita in un oggetto di tipo data.frame:

> tab <- as.data.frame(tab)
> head(tab)
  item1 item2 Freq
1     1     1    5
2     2     1    3
3     3     1    3
4     4     1    2
5     5     1    0
6     1     2    2

Grafico a bolle (bubble chart)


Quello che manca al grafico costruito poco sopra è l’informazione sul numero di osservazioni in ogni coordinata. Il modo più semplice di considerare quella che è a tutti gli effetti una terza variabile è fare in modo che il diametro di ogni punto dipenda dalla frequenza. Verrà creato così un grafico nel quale saranno presenti punti più grandi e punti più piccoli: più grande sarà il punto, maggiore sarà la concentrazione di dati.

Per realizzare questo grafico possiamo usare il comando symbols, specificando nell’argomento inches un’unità di misura per calibrare la dimensione dei punti.

with(tab, symbols(item1, item2, Freq, inches=0.6))

Bubble-plot fra item1 e item2

Il risultato conferma che la densità è maggiore sulla diagonale e va diminuendo con l’allontanarsi da questa. I dati quindi non sono sparpagliati in maniera casuale come poteva sembrare nel primo grafico, ma la relazione fra item1 e item2 segue un andamento ben preciso (nello specifico lineare).

Grafico a mattonelle (tile plot)


Un altro tipo di grafico che ci viene in aiuto è il tile plot. In questo tipo di visualizzazione, i dati sono rappresentati attraverso delle mattonelle che vengono colorate a seconda del valore assunto da una terza variabile. Per costruire il tileplot dobbiamo installare e attivare il pacchetto ggplot2 (del quale abbiamo già parlato).

Allo strato di base costruito con il comando ggplot dobbiamo aggiungere un livello creato con geom_tile e un gradiente di colore con scale_fill_gradient; infine, possiamo specificare un tema (io ho scelto theme_bw):

library(ggplot2)
ggplot(data=tab, aes(x=item1, y=item2, fill=Freq)) +
    geom_tile(colour="white") +
    scale_fill_gradient(low="white", high="red3") +
    theme_bw()

Tile-plot fra item1 e item2

Il grafico a mattonelle è forse quello più accattivante, ma probabilmente anche il più complicato da costruire, visto che richiede l’uso di ggplot2.

E voi, quali soluzioni prediligete in questi casi?

Risolvere pRoblemi

Risolvere problemi è il metodo migliore per imparare qualcosa. Ricordate la scuola?

Con la programmazione in R è un po’ la stessa cosa. Risolvere problemi favorisce la dimestichezza con il programma e facilita l’apprendimento nell’uso dei vari pacchetti. Il suggerimento è di iniziare da cose semplici, come quelle che potete trovare in un manuale o nei siti di discussione.

Di recente l’utente Umesh Acharya ha postato un quesito su CrossValidated, un sito che si occupa di problemi di statistica. Il quesito in realtà è di natura informatica, poiché riguarda la codifica di un plot. Fino a poco tempo fa, il quesito era reperibile qui, ma è stato ormai rimosso, essendo quel genere di domande più adatte a StackOverflow, il sito gemello di CrossValidated, ma più genericamente dedicato a problemi informatici.

Domanda Umesh: “Come posso mettere tre plot in un’unica finestra?”. La domanda non è banale. Umesh ha creato una funzione che consente di “stampare” nel plot la formula di una regressione usando i valori stimati per i parametri, e per farlo ha usato ggplot2, il programma di grafica creato da Hadley Wickham, mago della programmazione in R (su InsulaR se n’era già parlato qui).

A differenza del sistema grafico base, in ggplot2 non è possibile ripartire le finestre grafiche con il comando par (che avete visto usare in precedenti post). Bisogna agire sulle griglie. E bisogna saperlo.

Dunque, abbiamo un dataset con 6 variabili, che vogliamo rappresentare a coppie di due, coordinate in una regressione. Come si rappresentano i tre grafici in un’unica finestra? Iniziamo a costruire il nostro dataset, che chiameremo ‘tom’ (toy object model):

a1 <- seq(from=1, to=10, by=1)
a2 <- seq (from=2, to=20, by=2)
b1 <- seq(from=3, to=30, by=3)
b2 <- seq(from=4, to=40, by=4)
c1 <- seq(from=5, to=50, by=5)
c2 <- seq(from=2, to=29, by=3)

# combiniamo i vettori in una matrice con il comando cbind
dataframe <- cbind(a1,a2,b1,b2,c1,c2)

# trasformiamo la matrice in un dataframe con etichette per l’intestazione delle variabili
tom <- as.data.frame(dataframe)

E adesso la bella funzione creata dal nostro Umesh per inserire il risultato della regressione nel grafico:

## function to create equation expression
lm_eqn = function(x, y, df){
    m <- lm(y ~ x, df);
    eq <- substitute(italic(y) == b %.% italic(x) + a,
    list(a = format(coef(m)[1], digits = 2),
    b = format(coef(m)[2], digits = 2)))
    as.character(as.expression(eq));
}

Chiamiamo il pacchetto:

library (ggplot2)

Creiamo i tre grafici in ggplot2:

################ a1 and a2 couple of variables
P1<-ggplot(tom, aes(x=a1, y=a2)) +
geom_point(shape=1) +      # Use hollow circles

geom_smooth(method=lm,    # Add linear regression line

se=FALSE)     # Don't add shaded confidence region

P2<- P1 + labs (x= "a1 value", y = "a2 value")## add x and y labels

P3 <- P2 + theme(axis.title.x = element_text(face="bold", size=20)) +
labs(x="a1 value")                            #label and change font size

P4 <- P3 + scale_x_continuous("a1 value",
limits=c(-10,60),
breaks=seq(-10, 60, 10))  ##adjust axis limits and breaks

##add regression equation using annotate
P5a <- P4 + annotate("text", x = 30, y = 10, label = lm_eqn(tom$a1, tom$a2, tom), color="black", size = 5, parse=TRUE)

P5a

Variabili a1 e a2

################ b1 and b2 couple of variables
P1b<-ggplot(tom, aes(x=b1, y=b2)) +
geom_point(shape=1) +      # Use hollow circles
geom_smooth(method=lm,    # Add linear regression line
se=FALSE)     # Don't add shaded confidence region

P2b<- P1b + labs (x= "b1 value", y = "b2 value")## add x and y labels

P3b <- P2b + theme(axis.title.x = element_text(face="bold", size=20)) +
labs(x="b1 value")                            #label and change font size
P4b <- P3b + scale_x_continuous("b1 value",
limits=c(-10,60),
breaks=seq(-10, 60, 10))  ##adjust axis limits and breaks

##add regression equation using annotate
P5b <- P4b + annotate("text", x = 40, y = 20, label = lm_eqn(tom$b1, tom$b2, tom), color="black", size = 5, parse=TRUE)

P5b

Variabili b1 e b2

################ c1 and c2 couple of variables
P1c<-ggplot(tom, aes(x=c1, y=c2)) +
geom_point(shape=1) +      # Use hollow circles
geom_smooth(method=lm,    # Add linear regression line
se=FALSE)     # Don't add shaded confidence region

P2c<- P1c + labs (x= "c1 value", y = "c2 value")## add x and y labels

P3c <- P2c + theme(axis.title.x = element_text(face="bold", size=20)) +
labs(x="c1 value")                            #label and change font size

P4c <- P3c + scale_x_continuous("c1 value",
limits=c(-10,60),
breaks=seq(-10, 60, 10))  ##adjust axis limits and breaks

##add regression equation using annotate
P5c <- P4c + annotate("text", x = 40, y = 15, label = lm_eqn(tom$c1, tom$c2, tom), color="black", size = 5, parse=TRUE)

P5c

Variabili c1 e c2

E adesso il gran finale. Come rappresentare i tre grafici in un’unica finestra?

Se il nostro Umesh, peraltro bravo programmatore, fosse stato meno pigro, avrebbe scoperto subito che CrossValidated non era il sito che faceva per lui, e avrebbe scoperto in fretta almeno due soluzioni al suo problema.

Le soluzioni che qui propongo sono tratte dal sito Cookbook for R, curato da Wiston Chang, una autentica miniera di gemme.

La prima soluzione utilizza il sistema di gestione delle griglie, e fa uso di due librerie aggiuntive a ggplot2 (librerie che dovrete scaricare se volete usarle).

library(grid)
library(gridExtra)

# semplice ed elegante (il titolo lo scegliete voi)
grid.arrange(P5a, P5b, P5c, ncol = 3, main = "Your main title")
# after saving, dev.off()
# se volete cambiare le dimensioni del titolo, seguite le istruzioni

### changing dimensions of the title
grid.arrange(P5a, P5b, P5c, ncol = 3,
main=textGrob("Your main title", gp=gpar(fontsize=20,font=3)))

Combinazione grafici

La seconda soluzione fa ricorso ad una funzione creata da Chang, e messa cortesemente a disposizione degli utenti dal creatore (il risultato è analogo a quello riportato sopra).


# Multiple plot function
# ggplot objects can be passed in …, or to plotlist (as a list of ggplot objects)
# – cols: Number of columns in layout
# – layout: A matrix specifying the layout. If present, ‘cols’ is ignored.
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
# from: http://www.cookbook-r.com/

multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) { require(grid) # Make a list from the ... arguments and plotlist plots <- c(list(...), plotlist) numPlots = length(plots) # If layout is NULL, then use 'cols' to determine layout if (is.null(layout)) { # Make the panel # ncol: Number of columns of plots # nrow: Number of rows needed, calculated from # of cols layout <- matrix(seq(1, cols * ceiling(numPlots/cols)), ncol = cols, nrow = ceiling(numPlots/cols)) } if (numPlots==1) { print(plots[[1]]) } else { # Set up the page grid.newpage() pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout)))) # Make each plot, in the correct location for (i in 1:numPlots) { # Get the i,j matrix positions of the regions that contain this subplot matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE)) print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row, layout.pos.col = matchidx$col)) } } } # Una volta che avete caricata la funzione nell’area di lavoro, l’uso è semplicissimo # (Il numero di colonne (in questo caso 3, ma può variare a piacimento): multiplot(P5a, P5b, P5c, cols=3) [/code] That's all, folks! Antonello Preti Stay Tuned for our next episode!

Creare una mappa colorata dell’Italia con mapIT

Attenzione: questo post è stato aggiornato rispetto alla pubblicazione originale per adeguare il codice agli ultimi aggiornamenti apportati alle funzioni descritte. Si ringrazia Marco Bertoletti per la segnalazione e il supporto nello sviluppo del pacchetto mapIT. [4 giugno 2015]
In R ci sono diverse pacchetti che permettono di disegnare mappe. Ormai ho perso il conto, ma quelle che sicuramente meritano almeno una citazione sono sp e ggmap. Nonostante la grossa disponibilità di funzioni R dedicate a questo tema, devo ammettere che, quando in passato mi sono trovato davanti al problema di rappresentare una semplicissima mappa dell’Italia con le regioni colorate a seconda dell’intensità di una variabile, sono entrato in crisi.

La maggior parte delle funzioni che avevo trovato erano molto semplici da usare per rappresentare aree degli Stati Uniti, ma dovendo raffigurare l’Italia le cose si complicavano parecchio. Mi aspettavo che, con R, realizzare una choropleth map (così si chiama il grafico in cui un’area geografica è rappresentata colorando in maniera diversificata le varie porzioni di territorio) fosse cosa assai banale. Non fu affatto così… trovai le procedure descritte nei tutorial fin troppo complicate rispetto alla banalità del grafico che volevo realizzare (qui si trova comunque una bella guida).

Mi resi conto di non essere l’unico utente R ad avere questo problema. Diverso tempo fa, su Statistica@Ning, Lorenzo di Blasio aveva proposto una soluzione in un bel tutorial che descriveva come costruire una mappa delle regioni italiane con ggplot2. Sintetizzando il codice proposto da Lorenzo, io avevo assemblato una funzione per creare la mappa in maniera rapida e semplificata; infine, Nicola Sturaro del gruppo MilanoR aveva preso in mano il codice e l’aveva decisamente migliorato e completato, inserendolo dentro un pacchetto: mapIT.

Attualmente, il pacchetto mapIT risiede in un repository su GitHub; per installarla si utilizza devtools, di cui abbiamo già parlato:

library(devtools)
install_github("quantide/mapIT")

La prima volta che utilizzai mapIT fu per un lavoro realizzato in collaborazione con Claudia Foti, studentessa all’Università di Messina, che aveva raccolto dei dati relativi alla valutazione di vini da parte di alcune guide specializzate. Avevamo la necessità di visualizzare, per ogni regione, il numero di cantine i cui vini erano stati recensiti.

Di seguito sono riportati i dati, organizzati in un data frame a due colonne, la prima che indica la regione e la seconda il numero di cantine.

vino <- data.frame(
    Regione = c("Abruzzo", "Basilicata", "Calabria", "Campania", "Emilia-Romagna",
                "Friuli-Venezia Giulia", "Lazio", "Liguria", "Lombardia", "Marche",
                "Molise", "Piemonte", "Puglia", "Sardegna", "Sicilia", "Toscana",
                "Trentino-Alto Adige", "Umbria", "Valle d\'Aosta", "Veneto"),
    Num.Cantine = c(22, 8, 9, 35, 24, 74, 19, 8, 41, 29, 5, 191, 22, 14, 40, 173,
                    57, 29, 6, 92)
)
&#91;/code&#93;

I nomi delle regioni possono essere scritti sia in minuscolo che in maiuscolo; spazi e altri caratteri non alfabetici vengono ignorati. Si può quindi scrivere indifferentemente: &lsquo;Trentino-Alto Adige&rsquo;, &lsquo;Trentino Alto Adige&rsquo; o &lsquo;TrentinoAltoAdige&rsquo;. Per le regioni con denominazione bilingue, viene riconosciuta la sola dicitura in italiano.

Per costruire la mappa delle regioni italiane, il pacchetto mapIT mette a disposizione l'omonima funzione <b>mapIT()</b>. Il primo argomento da passare alla funzione è la variabile numerica (Num.Cantine) e il secondo la variabile che specifica a quale regione italiana ogni dato si riferisce (Regione). Eventualmente, può essere passato un terzo argomento, costituito dal dataset dal quale le variabili andranno estrapolate.

Inoltre, sono disponibili dei parametri aggiuntivi per modificare l'aspetto grafico, che vanno passati attraverso una lista di nome <b>graphPar</b>. Io qui ne utilizzo uno, <b>guide.label</b>, che specifica l'etichetta che dovrà essere utilizzata come titolo della legenda a lato.

[code language="r"]
library(mapIT)
mapIT(Num.Cantine, Regione, data=vino, graphPar = list(guide.label="Numero\nCantine"))

La sequenza di escape ‘\n’, utilizzata nella stringa passata a guide.label, serve per mandare accapo il testo. Questo è il grafico risultante:

Mappa regioni italiane

Facile, no? È bastato caricare il pacchetto e lanciare una brevissima istruzione!

Il grafico può essere personalizzato agendo sull’argomento graphPar. Questa lista può contenere una lunga sequenza di dettagli che definiscono l’aspetto finale del grafico (per i dettagli, si veda l’help della funzione). Una delle prime cose che sicuramente vorremo fare sarà alterare i colori. Per alterare i colori bisogna specificare, nella lista da passare a graphPar, il colore da attribuire al valore minimo (low) e il colore da attribuire al valore massimo (high):

gp <- list(guide.label="Numero\nCantine", low="#fff0f0", high="red3")
&#91;/code&#93;

Per comodità, ho salvato questi valori nell'oggetto gp; si noti che i colori possono essere specificati sia utilizzando il <a href="https://it.wikipedia.org/wiki/Lista_dei_colori" target="_blank">codice esadecimale</a> ("#fff0f0") che utilizzando le parole chiave che definiscono i colori ("red3").

Ora, rilanciamo il comando passando la lista gp all'argomento graphPar:

[code language="r"]
mapIT(Num.Cantine, Regione, data=vino, graphPar=gp)

Mappa regioni italiane in rosso

Potete giocare con i colori per trovare la configurazione che preferite maggiormente. Per individuare il codice esadecimale dei colori si può usare un applicativo web come RGB color picker.

Per rendere il grafico in bianco e nero bisogna sempre giocare con i valori low e high di graphPar. In questo caso, per rendere il grafico un pochino più accattivante, potremmo sfruttare i temi di ggplot2; il primo esempio proposto di seguito sfrutta il tema theme_bw e produce il grafico di sinistra, mentre il secondo esempio sfrutta il tema theme_grey e produce il grafico di destra.


library(ggplot2)

# Tema: black and white
gp <- list(guide.label="Numero\nCantine", low="white", high="gray20", theme=theme_bw()) mapIT(Num.Cantine, Regione, data=vino, graphPar=gp) # Tema: grey gp <- list(guide.label="Numero\nCantine", low="white", high="gray20", theme=theme_grey()) mapIT(Num.Cantine, Regione, data=vino, graphPar=gp) [/code] Mappa regioni italiane in bianco e nero

Ci sono ancora diverse funzionalità da implementare e non escluderei che in futuro alcune cose possano cambiare. Chi avesse idee su come migliorare mapIT o dovesse riscontrare qualche malfunzionamento, può aprire un issue su GitHub in modo da darci una mano nello sviluppo.

Visualizzare i dati con ggplot2

Uno dei motivi che spingono molte persone che si occupano di analisi dati ad avvicinarsi a R è la sua capacità di generare grafici accattivanti e adatti a ogni esigenza. R possiede tante librerie che permettono di creare visualizzazioni, anche interattive, ma ce n’è una che negli ultimi anni ha preso prepotentemente piede: ggplot2.

Per comprendere l’entità dell’esplosione del fenomeno, possiamo osservare l’andamento temporale delle ricerche su google che utilizzano “ggplot2” come parola chiave: dal 2009 a oggi (giugno 2013), il trend appare in rapidissima crescita.

Creata nel 2005 da Hadley Wickham, ggplot2 premette di generare dei grafici decisamente più raffinati e attraenti rispetto a quelli che si possono ottenere con il pacchetto grafico contenuto nella distribuzione base di R. La libreria permette di gestire tantissimi parametri in grado di rendere estremamente elegante il risultato finale. La sua logica di funzionamento però non è proprio intuitiva, soprattutto perché è veramente diversa da quella a cui un utente R è comunemente abituato.

La libreria ggplot2 è un’implementazione della cosiddetta “Grammar of Graphics” di Wilkinson. Tale “grammatica” consiste in uno schema generale da applicare alla visualizzazione dei dati, che permette di organizzare un grafico attraverso la combinazione di componenti semantiche distinte, come oggetti geometrici, scale e coordinate.

Fondamentalmente, la funzione da cui si parte per inizializzare un grafico è ggplot. La definizione della tipologia di grafico e i vari parametri saranno definiti successivamente, letteralmente aggiungendo all’oggetto tutte le componenti necessarie. Saranno quindi altre funzioni, come geom_bar, geom_line o geom_point a occuparsi di aggiungere al livello di base barre, linee, punti, e così via. Infine, tramite altre funzioni come xlab, ylab e ggtitle, sarà possibile definire i dettagli più fini.

Descrivere in un unico post tutte le possibilità creative offerte da ggplot2 sarebbe davvero un’impresa ardua. Qui vedremo giusto i rudimenti, in modo da comprendere la filosofia di questa implementazione della “grammatica della grafica”. A titolo eseplificativo utilizzeremo un dataset del Ministero della salute che descrive il numero di posti letto ospedalieri disponibili nel 2011. Da questa pagina è possibile scaricare il dataset, anche se qui lo caricheremo in R direttamente dal web.

beds <- read.csv2("http://www.dati.salute.gov.it/imgs/C_17_dataset_18_download_itemDownload_0_upFile.csv",header=TRUE)
&#91;/code&#93;

<p style="text-align: justify;">Il dataset contiene diverse variabili, ma noi utilizzeremo solo <i>Totale.posti.letto</i> e <i>Tipo.di.Disciplina</i>, che è una variabile di tipo fattore che classifica i posti letto secondo tre categorie: Acuti, Lungodegenza e Riabilitazione. Quello che faremo adesso è costruire un grafico a barre per visualizzare il numero totale di posti letto per ogni tipo di discplina.</p>

<p style="text-align: justify;">Questo è il grafico che arriveremo a costruire:</p>

<img src="http://www.insular.it/wp-content/gallery/post-images/posti_letto.png" width="70%" height="70%" alt="Posti letto">

<p style="text-align: justify;">Per prima cosa, dobbiamo calcolare il numero totale di posti letto per ogni disciplina e inserirli in un nuovo dataset. Questo dataset dovrà contenere anche una variabile che specifica a quale tipo di disciplina fa rifimento ogni valore:</p>

[code language="r"]
df <- data.frame(
    num = tapply(beds$Totale.posti.letto, beds$Tipo.di.Disciplina, sum),
    type = levels(beds$Tipo.di.Disciplina)
)
&#91;/code&#93;

<p style="text-align: justify;">Ora trasformiamo i valori contenuti nella variabile <i>num</i> in percentuali, e salviamoli in una nuova colonna del dataset:</p>

[code language="r"]
df$perc <- 100*(df$num/sum(df$num))
&#91;/code&#93;

<p style="text-align: justify;">Questi valori saranno posizionati in cima a ogni barra, come mostrato nel grafico poco sopra. Arrotondiamoli alla prima cifra decimale e specifichiamo chiaramente che si tratta di percentuali aggiungendo il simbolo "%":</p>

[code language="r"]
df$perc <- round(df$perc,1)
df$perc <- paste(df$perc,"%",sep="")
&#91;/code&#93;

<p style="text-align: justify;">Adesso abbiamo tutto l'occorrente per visualizzare i dati. Il primo passaggio, oltre ad attivare la libreria, consiste nell'inizializzare l'oggetto attraverso la funzione ggplot.</p>

[code language="r"]
library(ggplot2)
gp <- ggplot(df, aes(x=type, y=num, fill=type))
&#91;/code&#93;

<p style="text-align: justify;">La funzione ggplot richiede due argomenti. Il primo è l'oggetto di tipo <i>data.frame</i> che contiene i dati da visualizzare. Il secondo è una particolare lista che viene generata dalla funzione <b>aes</b>, la quale determina l'aspetto (aesthetic) del grafico. La funzione aes richiede necessariamente di specificare "x" e "y", ovvero i nomi delle colonne del dataframe "df", che rappresentano le variabili da porre rispettivamente sugli assi orizzontale e verticale.</p>

<p style="text-align: justify;">Altri argomenti molto utilizzati sono "fill", per specificare quale variabile utilizzare per disporre i colori di riempimento degli oggetti da creare, "group", per specificare un fattore di raggruppamento (necessario negli interaction plot), e "ymin" e "ymax", per determinare i limiti dell'asse verticale.</p>

<p style="text-align: justify;">Ora dobbiamo creare il livello che contiene le barre utilizzando la funzione <b>geom_bar</b>:</p>

[code language="r"]
bar <- geom_bar(stat="identity",show_guide=TRUE)
&#91;/code&#93;

<p style="text-align: justify;">Sono stati esplicitati due parametri: "stat", che specifica quale trasformazione applicare sui dati, e "show_guide", che, se impostato a TRUE, mostrerà a lato una legenda. Noi non abbiamo applicato nessuna trasformazione sui dati (stat="identity") e abbiamo chiesto di mostrare la legenda (in realtà, per default l'argomento è già impostato a TRUE).</p>

<p style="text-align: justify;">A questo punto, i due livelli necessari per la creazione del grafico sono stati creati, e potremmo già concludere qui. Ma ci sono alcune cose che ancora potremmo fare, come aggiungere in cima alle barre delle etichette che specificano i valori percentuali:</p>

[code language="r"]
lab <- geom_text(aes(x=type, y=num, label=perc, vjust=-0.3))
&#91;/code&#93;

<p style="text-align: justify;">Per creare le etichette si utilizza <b>geom_text</b>; ancora, nel codice ritorna la funzione aes. In questo caso, oltre alle coordinate "x" e "y", sono state specificate le etichette ("label") ed è stato impostato un valore di scostamento verticale dalla cima delle barre ("vjust"), per lasciare un po' di spazio tra l'etichetta e la rispettiva barra.</p>

<p style="text-align: justify;">Attraverso le funzioni <b>guides</b> e <b>guide_legend</b> è possibile modificare il titolo della legenda:</p>

[code language="r"]
leg <- guides(fill=guide_legend(title="Posti letto"))
&#91;/code&#93;

<p style="text-align: justify;">Utilizzando <b>xlab</b> e <b>ylab</b>, possiamo creare le etichette da apporre sugli assi orizzontale e verticale:</p>

[code language="r"]
lx <- xlab("Tipo di disciplina")
ly <- ylab("Numero totale")
&#91;/code&#93;

<p style="text-align: justify;">Infine, per creare il grafico, dobbiamo combinare tutti gli oggetti creati in un'unica visualizzazione:</p>

[code language="r"]
gp + bar + lab + lx + ly + leg

Il grafico sarà quindi generato e pronto per essere salvato.

Le possibilità creative offerte da ggplot2 sono veramente tante e tutte molto attraenti. Ma creare un grafico di questo tipo può risultare lungo e piuttosto macchinoso se non si ha una discreta manualità nel gestire la speciale sitassi della libreria. Tendenzialmente, in fase di esplorazione dei dati io preferisco altre soluzioni, più grezze ma immediate; tuttavia, una volta che ho definito esattamente quali grafici presentare, difficilmente ho dubbi su quale libreria scegliere.

Di seguito si riassume tutto il codice utilizzato.


# Preparazione dei dati:
beds <- read.csv2("http://www.dati.salute.gov.it/imgs/C_17_dataset_18_download_itemDownload_0_upFile.csv",header=TRUE) num <- tapply(beds$Totale.posti.letto, beds$Tipo.di.Disciplina, sum) type <- levels(beds$Tipo.di.Disciplina) df <- data.frame(num,type) df$perc <- 100*(df$num/sum(df$num)) df$perc <- round(df$perc,1) df$perc <- paste(df$perc,"%",sep="") # Costruzione del grafico: library(ggplot2) gp <- ggplot(df, aes(x=type, y=num, fill=type)) bar <- geom_bar(stat="identity",show_guide=TRUE) lab <- geom_text(aes(x=type, y=num, label=perc, vjust=-0.3)) leg <- guides(fill=guide_legend(title="Posti letto")) lx <- xlab("Tipo di disciplina") ly <- ylab("Numero totale") gp + bar + lab + lx + ly + leg [/code]