Archivio tag: grafici

Visualizzare le strutture di correlazione con “qgraph”

Non so voi ma io ho una predilezione per le rappresentazioni grafiche, che si manifesta soprattutto in fase di ricognizione dei dati. Già Davide in uno dei suoi ultimi post aveva rimarcato l’importanza di visualizzare i dati, importanza che non posso che condividere! Nello specifico, il problema descritto da Davide consisteva nel rappresentare graficamente una relazione bivariata in cui le variabili considerate erano misurate su scala Likert. Tali relazioni apparivano difficilmente interpretabili con il classico grafico di dispersione (o scatterplot). La soluzione proposta – ovvero rappresentare la densità delle variabili sul diagramma – è sicuramente ottima, ma in alcuni casi può rivelarsi poco pratica, ad esempio nel caso in cui:

  1. si devono visualizzare più relazioni bivariate (ad esempio, tra i diversi item di un questionario);
  2. si vuole avere una prima idea delle relazioni che legano tra loro le variabili indagate (ad esempio, come accade quando si effettua un’indagine esplorativa dei dati).

Per l’analisi dei dati di un questionario che ho utilizzato per la mia tesi di laurea cercavo un metodo semplice e veloce per visualizzare le relazioni tra gli item. Ero già rassegnata a dover scrutare le matrici di correlazione in cerca di qualche relazione interessante, quando mi sono imbattuta per caso in un pacchetto di facile utilizzo e comprensione: qgraph. Questa libreria permette di creare una struttura reticolare in cui ogni nodo rappresenta una variabile e ogni connessione rappresenta una relazione. In particolare è possibile visualizzare:

  1. la forza della relazione attraverso lo spessore delle linee di connessione (linee più spesse indicano relazioni più forti);
  2. la direzione della relazione attraverso il colore delle linee di connessione (linee verdi indicano una correlazione positiva mentre linee rosse indicano una correlazione negativa);
  3. la significatività della correlazione in termini di p-value.

In realtà la libreria permette di fare tante altre cose interessanti, ma ritengo sia utile iniziare dalle basi ed eventualmente approfondire altre forme di visualizzazione in un diverso post. Per mostrare l’utilizzo della libreria ricorrerò ad un caso emblematico che sicuramente sarà il pane quotidiano di molti studenti – ma non solo – di psicologia: le relazioni tra gli item di un questionario.

La libreria qgraph è ampiamente utilizzata sia per l’analisi di variabili latenti che rappresentano costrutti di personalità (come i Big Five), sia per la visualizzazione delle relazioni dirette tra variabili osservate. Prima di iniziare occorre però fare una precisazione.

Bisogna ricordare che le risposte di un questionario su scala Likert sono variabili di tipo categoriale ordinale e, come tali, godono di proprietà diverse da quelle possedute dalle variabili quantitative (sareste capaci di fare la media tra “per niente d’accordo” e “assolutamente d’accordo”?). In alcuni casi la natura categoriale delle variabili ordinali viene forzata assegnando loro un numero e trattandole di fatto come numeriche. Questa forzatura ha dei pro (ad esempio, facilitare la codifica e l’interpretazione dei risultati) e dei contro. Rimando ad una lettura interessante che tratta alcuni dei “contro”.

Ora vediamo la libreria in azione!

Il file cor.item.rda è un’area di lavoro di R che contiene una matrice di correlazione (cor.item) tra i 24 item di un questionario proposto a 100 ragazzi di 14 anni. Per ogni item si chiedeva ai partecipanti alla ricerca di esprimere un giudizio su una scala Likert da 1 (“per nulla”) a 5 (“moltissimo”). Tenendo conto della natura ordinale degli item è stata calcolata la matrice di correlazione policorica attraverso la funzione auto_cor della stessa libreria qgraph (tale funzione permette di calcolare in modo statisticamente appropriato le correlazioni tra variabili quantitative, ordinali e anche tra variabili ordinali e quantitative, vedi qui).

View(cor.item)

La visione della matrice di correlazione tra i 24 item non è certo di immediata interpretazione.

Installiamo e carichiamo la libreria qgraph:

install.packages("qgraph")
library(qgraph)

Quindi, utilizziamo la funzione qgraph per visualizzare la relazione fra gli item, utilizzando l’argomento vsize per definire manualmente la dimensione dei nodi:

qgraph(cor.item, vsize=5)

Grafico 1

Il grafico mostra gli item del questionario in relazione di tipo “tutto con tutto”. Lo spessore delle linee di collegamento indica la forza della relazione: appare evidente come siano presenti correlazioni decisamente più forti di altre. Ho ritenuto opportuno tralasciare le correlazioni che avevano un indice di correlazione inferiore a .50 con l’argomento minimum=0.5.

qgraph(cor.item, vsize=5, minimum=0.5)

Grafico 2

Consideriamo la relazione fra tre item, ad esempio l’item8.b, l’item3.b e l’item7.b: il primo correla negativamente con il secondo (il coefficiente di correlazione è infatti -0.51), il quale invece correla positivamente con il terzo (il suo coefficiente di correlazione è infatti 0.59).

Una funzione utile è quella che permette di visualizzare la struttura di correlazione tra gli item del questionario raggruppandoli secondo un determinato criterio. Lo strumento che stavo studiando io presentava tre categorie di item; se notate, infatti, il nome dell’item è composto da un numero e da una lettera, che può essere a, b oppure c: è proprio questa lettera a identificare a quale raggruppamento l’item appartiene.

Per raggruppare gli item nel grafico è prima di tutto necessario creare una lista che definisca i gruppi cui fanno riferimento le variabili.

list.cor = list(
    a = c(1,4,7,10,13,16,19,22),
    b = c(2,5,8,11,14,17,20,23),
    c = c(3,6,9,12,15,18,21,24))

La lista list.cor contiene al suo interno tre vettori e ogni vettore riporta gli indici di colonna degli item di ciascun raggruppamento.

A questo punto creiamo un vettore di nome lab (labels) che contiene dei nuovi nomi da attribuire alle variabili; si tratta di un passaggio opzionale, ma che renderà il grafico più leggibile e le variabili immediatamente identificabili. Il seguente codice estrae i nomi delle variabili ed elimina la stringa “item” da ogni nome. In questo modo, la stringa “item1.a” diventerà “1.a”, la stringa “item1.b” diventerà “1.b”, e così via.

lab = gsub("item","",rownames(cor.item))

Un altro aspetto opzionale, ma sicuramente utilissimo, è l’uso dei colori. Nel vettore hue salviamo un vettore di colori che dovranno essere usati per marcare in maniera diversa i nodi che rappresentano le variabili afferenti ai tre gruppi:

hue = c("dodgerblue3","darkgoldenrod1","snow")

Infine, possiamo costruire il grafico:

qgraph(cor.item, vsize=5, minimum=0.5, groups=list.cor, color=hue, labels=lab, edge.label.cex=3)

Grafico 3

Molto più ordinato, no?

Al posto dei valori di correlazione è possibile visualizzare i p-value che indicano se gli indici possono essere considerati significativamente diversi da zero. Anche in questo caso la libreria si rivela molto comoda, perché permette di visualizzare la significatività dei parametri di regressione aggiungendo l’argomento graph = “sig2″ come segue:

qgraph(cor.item, minimum=0.5, vsize=5, groups=list.cor, graph="sig2", color=hue, labels=lab, alpha=c(0.01,0.05))

Grafico 4

Le linee blu indicano la significatività (al 5% e all’1%) delle correlazioni positive, mentre le linee arancioni indicano la significatività delle correlazioni negative (sempre al 5% e all’1%).

La mia indagine sulle relazioni tra gli item del questionario non finisce certo qui, questa libreria infatti mi sta aiutando a pianificare le indagini successive!

Spero di riuscire presto a mostrarvi altri grafici “in azione” con le funzioni sem e factanal (molto utili in psicologia).

Info e fonti:

  1. qgraph: Network Visualizations of Relationships in Psychometric Data
  2. State of the aRt personality research: A tutorial on network analysis of personality data in R
  3. Network Model Selection Using qgraph 1.3
  4. qgraph examples

Usare i gRafici in R

Tavolozza

Predicare ai convertiti. Così dicono gli Americani.

Noi diremmo “sfondare una porta aperta”.

L’argomento è stato già trattato più volte. Comunque, repetita iuvant.

Uno dei vantaggi di R, e non dei minori, è la sua estrema ricchezza e flessibilità sul piano grafico. Nel suo formato base R ha un sofisticato sistema di rappresentazione grafica dei dati, che consente di avere una rappresentazione dei dati utile alla comprensione delle relazioni sottese.

Questa disponibilità grafica è ulteriormente arricchita dagli sviluppatori, che non mancano di dedicare degli script alla rappresentazione grafica dei dati secondo l’analisi proposta nel pacchetto cui contribuiscono.

Alcuni pacchetti sono stati sviluppati in modo specifico per rendere ancora più versatili le capacità grafiche di R. Alcuni di questi pacchetti gestiscono le forme geometriche, altri sono dedicati alle palettes, le disposizioni dei colori in un grafico, una utilità che chi deve creare grafici per lavoro è in grado di apprezzare con gratitudine.

L’importanza della rappresentazione grafica dei dati è testimoniata dalla frequenza con la quale sono scaricati i pacchetti specificamente dedicati.

Tra i pacchetti di R maggiormente scaricati figurano: ggplot2, colorspace, RColorBrewer, Scales, lattice.

Un passo indietro.

La rappresentazione grafica dei dati è importante, e permette di raggiungere una intuitiva e più immediata consapevolezza delle relazioni statistiche tra le variabili.

Usare R facilmente conduce alla scoperta di questa ovvietà.

Appena raggiunto il satori la prima reazione è quella di incazzarsi come una iena del Serengeti (copyleft, Paolo Villaggio, per i più distratti).

Se il programma statistico su cui avete studiato avesse avuto una migliore interfaccia grafica – vi verrà spontaneo pensare – avreste compreso meglio e più in fretta le basi della statistica. Ma la maggior parte dei programmi statistici commerciali concentra il focus sull’ottenimento della preziosa p < .05, e molte cose sono ad essa sacrificate.

Di seguito, facendo riferimento a dataset disponibili in R, riassumo qualche giochino utile; potrete copiare e incollare i comandi direttamente in R.

Caricate il pacchetto (già disponibile in R) e usate attach per rendere il dataset immediatamente accessibile. Dopo aver usato attach, potrete chiamare le variabili direttamente con il loro nome, risparmiandovi la seccatura di dovere specificare di continuo iris$variabile.

data(iris)
attach(iris)

Ora ottenete una descrizione del dataset:

dim(iris)
head(iris)

La funzione pairs vi consente di ottenere una matrice di correlazione delle variabili del dataset. Ogni variabile è posta in correlazione con le altre: intuitiva la comprensione di come la matrice deve essere letta. Sconsigliabile usarla con dataset con più di 10 variabili; nel caso, scomponete il dataset in vari insiemi. Come? Ripassate la lezione introduttiva su R… è possibile “forzare” pairs a fare cose parecchio interessanti date un’occhiata al manuale online.

pairs(iris)

pairs

Volete sapere se esiste una relazione tra lunghezza dei petali e lunghezza dei sepali in un fiore? Usate plot, che utilizza il formato plot(x,y): prima la variabile che va sull’asse delle x, poi quella che va sull’asse delle y.

plot(Petal.Length, Sepal.Length)

Un metodo alternativo per specificare l’ordine delle variabili in un grafico è usare il formato plot(y~x): la variabile che precede la tilde (il simbolo ~) è la variabile dipendente, che verrà posta sull’asse y, mentre la variabile inserita dopo la tilde è la variabile indipendente, che verrà posta sull’asse delle x.

plot(Sepal.Length ~ Petal.Length, data = iris)

Sembra proprio che esista una relazione lineare, con varianza spiegata pari al 75.8%. Volete esserne sicuri? Provate una regressione lineare:

fit  <- lm(Sepal.Length ~ Petal.Length, data = iris)
summary(fit)

Aggiungete la retta di regressione al grafico:

abline(fit)

Aggiungete la curva della local regression, una regressione non-parametrica. Cosa è lowess? Studiatevelo, vi tornerà utile!

fit2 <- lowess(Sepal.Length ~ Petal.Length)
lines(fit2, col = "red")

plot

Non male, la curva della local regression non si discosta troppo dalla retta della regressione lineare.

Volete l’intervallo di confidenza della retta della regressione lineare?

IntConf <- predict(fit, interval="confidence")

Nella matrice risultante, nelle colonne 2 e 3 si trovano i valori rispettivamente lower e upper dell’intervallo di confidenza della predizione. Le due linee dell’intervallo di confidenza vanno centrate sull’asse delle x (dove è il Petal.Length).

plot(Sepal.Length ~ Petal.Length)
abline(fit)
lines(Petal.Length, IntConf[,2], lty=3, col="blue")
lines(Petal.Length, IntConf[,3], lty=3, col="blue")

lines

Volete essere sicuri che la vostra regressione sia valida? Controllate le diagnostiche del modello. Sono quattro: nelle prime due (in alto) i residui dovrebbero avere una distribuzione casuale e la curva che li attraversa dovrebbe essere più o meno orizzontale; nel QQplot i vostri residui dovrebbero cadere sulla retta o non discostarsene troppo; infine, il quarto plot mostra i casi che violano la distanza di Cook, che dovrebbero essere pochi (sono numerati).

par(mfcol = c (2,2))
plot(fit)

La funzione par(mfcol = c(2,2)) serve a ripartire la lavagna grafica in quattro riquadri; se vi servono più riquadri appaiati, semplicemente variate gli input in c(num righe, num colonne).

plot(fit)

Nel complesso, non male.

Una migliore descrizione della violazione della distanza di Cook si ottiene con un plot del pacchetto car (da scaricare, se non lo avete), dove car sta per Companion to Applied Regression; creiamo un influence plot con punti proporzionali alla distanza di Cook (casi rilevanti identificati in rosso)

library(car)
layout(1)
influencePlot(fit, id.n=3,id.col="red")

Influence plot

Dato che prima, con il comando par(), avevamo ripartito la lavagna grafica in quattro riquadri, con layout(1) la riportiamo a un solo riquadro.

Sull’argomento delle regression diagnostics, utile riassunto qui, qui e qui. John Fox è il masterchef dell’argomento.

Volete avere una distribuzione della lunghezza dei petali nelle tre specie di fiori del dataframe? Perché non usare un bel density plot, sempre dal pacchetto car? La variabile di raggruppamento deve essere trattata come fattore e Species è già di classe “factor”. Non ci credete? Chiedetelo:

is.factor(Species)

La risposta è TRUE, mentre per is.numeric(Species) la risposta è FALSE. Se la vostra variabile non è un fattore, rendetela tale così (meglio assegnare un nuovo nome alla variabile, non si sa mai):

nuovo_nome_vostra_variabile <- as.factor(nome_vostra_variabile)

Ora possiamo andare sicuri a costruire i density plot:

par(mfcol = c(1,2))
densityPlot(Petal.Length~Species,data=iris)
densityPlot(Sepal.Length~Species,data=iris)

density plot

Bella differenza, eh?

Altra rappresentazione, ottenibile con un altro pacchetto, graphics (già installato e attivo nella distribuzione base di R) è il conditioning plot:

coplot(Sepal.Length ~ Petal.Length | Species, data = iris, panel = panel.smooth, rows = 1)

coplot

Il risultato suggerisce che per le tre specie esiste una relazione tra lunghezza dei petali e dei sepali, meno marcata per la specie setosa.

E adesso provate voi: caricare il dataframe mtcars:

data(mtcars)

Rapido check alle variabili:

head(mtcars)

E ora create un plot della relazione tra la variabile mpg (Miles/(US) gallon, miglia con un litro) e quella wt (weight, peso della macchina):

plot(mpg,wt)

Aha! messaggio di errore:

Errore in plot(disp, wt) : oggetto “mpg” non trovato

Capito perché è utile usare attach? Con attach potete nominare direttamente le variabili:

attach(mtcars)
plot(mpg,wt)

Ora funziona. Bene, proseguite con l’esercizio oppure variate a piacimento. Sbizzarritevi chiamando la lista dei dataset disponibili in R, digitando:

library(help = "datasets")

Per caricare il dataset, basta chiamarlo con: data(nome_del_dataset).

That’s all, folks!

Antonello Preti

Stay Tuned for our next episode!