Rimodellare i dati

Quando dobbiamo organizzare una tabella per raccogliere dati provenienti da disegni sperimentali, la prima domanda che dovremmo porci è come organizzarli. All’università mi hanno sempre ripetuto che a ogni riga deve corrispondere un “soggetto”, mentre a ogni colonna una variabile. Questa regola, ampiamente condivisa e sulla base della quale sono programmati i software statistici, in alcuni casi può diventare ambigua. Nello specifico, questo accade quando un soggetto (unità statistica) viene misurato più volte.

Per chiarire il concetto, passiamo subito a un caso pratico. Si tratta di un esempio inventato e abbastanza semplicistico, che nella sua semplicità ci aiuterà a definire meglio il problema.

In un laboratorio di psicofisiologia del sonno si stanno testando gli effetti di una nuova psicoterapia di tipo cognitivo-comportamentale e di un trattamento di tipo farmacologico per la cura dell’insonnia. Entrambi i trattamenti hanno la durata di due mesi.
Sono state selezionate 10 persone insonni con problemi nella fase di addormentamento: 5 vengono trattate con psicoterapia (PT) e 5 con terapia farmacologica (FT).
Il giorno prima dell’inizio del trattamento, a 30 e a 60 giorni viene registrato il numero di ore dormite da ogni individuo.
Per verificare la loro ipotesi, i ricercatori vorrebbero eseguire un’analisi statistica per verificare se le persone rispondono diversamente ai due trattamenti, valutando se questi portano a delle differenze nel numero di ore di sonno.

Dovendo organizzare i dati di questo disegno sperimentale, o si inseriscono i soggetti per riga oppure le variabili per colonna, ma non è possibile soddisfare i due criteri simultaneamente. Vediamo perché.

Nella tabella qui sotto, sono mostrati i dati raccolti nel cosiddetto formato wide.

sogg tratt tempo.0 tempo.30 tempo.60
1 PT 5.60 3.30 8.90
2 PT 4.80 4.70 7.90
3 PT 3.90 5.30 8.50
4 PT 5.80 4.50 8.20
5 PT 3.50 3.70 6.90
6 FT 3.90 4.70 7.00
7 FT 4.10 4.90 5.60
8 FT 5.00 3.80 5.30
9 FT 4.00 4.70 5.30
10 FT 4.00 4.80 6.30

Come possiamo osservare, è vero che a ogni riga corrisponde un soggetto, ma non è vero che a ogni colonna corrisponde una variabile. Infatti, il fattore “tempo” è stato suddiviso in tre colonne, una per ogni livello: 0 giorni (inizio), 30 giorni e 60 giorni. “tempo.0”, “tempo.30” e “tempo.60” non sono delle variabili, ma sono tutti livelli di un’unica variabile. Software come SPSS o STATISTICA richiedono i dati disposti proprio in questo modo.

Un altro modo in cui i dati possono essere organizzati è il formato long, che possiamo vedere qui di seguito.

sogg tempo tratt ore
1 0 PT 5.60
1 30 PT 3.30
1 60 PT 8.90
2 0 PT 4.80
2 30 PT 4.70
2 60 PT 7.90
3 0 PT 3.90
3 30 PT 5.30
3 60 PT 8.50
4 0 PT 5.80
4 30 PT 4.50
4 60 PT 8.20
5 0 PT 3.50
5 30 PT 3.70
5 60 PT 6.90
6 0 FT 3.90
6 30 FT 4.70
6 60 FT 7.00
7 0 FT 4.10
7 30 FT 4.90
7 60 FT 5.60
8 0 FT 5.00
8 30 FT 3.80
8 60 FT 5.30
9 0 FT 4.00
9 30 FT 4.70
9 60 FT 5.30
10 0 FT 4.00
10 30 FT 4.80
10 60 FT 6.30

In questo formato, a ogni colonna corrisponde una variabile, ma a ogni riga corrisponde un’osservazione e non un soggetto. Infatti, dato che i soggetti sono misurati tre volte, per ognuno di essi sono presenti tre righe.

Ognuno di questi formati ha dei pro e dei contro. Il formato wide, essendo più compatto, consente di visualizzare con più facilità la tabella e permette di utilizzare ognuno dei tre tempi come se fosse una variabile diversa (in alcuni casi può tornare utile). Tuttavia, trovo che il formato long sia migliore da un punto di vista concettuale, perché consente di individuare immediatamente quali sono le variabili di uno studio, distinguendo chiaramente la dipendente “ore di sonno” dalla indipendente “tempo” (questo aspetto non è da sottovalutare nell’insegnamento della statistica).

Eccetto casi particolari, le funzioni R richiedono che i dati siano disposti in formato long. Però, capita spesso che i dati siano stati registrati in formato wide. Talvolta ci si può trovare nella situazione di dover passare i propri dati in formato long a un utente di SPSS che, comprensibilmente, li gradirebbe in formato wide. È quindi importante capire come poter passare da un formato all’altro utilizzando R.

Da wide a long


Costruiamo in R la tabella di dati in formato wide:

sonno.wide <- data.frame(
    sogg = factor(c(1,2,3,4,5,6,7,8,9,10)),
    tratt = c("PT","PT","PT","PT","PT","FT","FT","FT","FT","FT"), 
    tempo.0 = c(5.6,4.8,3.9,5.8,3.5,3.9,4.1,5,4,4),
    tempo.30 = c(3.3,4.7,5.3,4.5,3.7,4.7,4.9,3.8,4.7,4.8),
    tempo.60 = c(8.9,7.9,8.5,8.2,6.9,7,5.6,5.3,5.3,6.3)
)
&#91;/code&#93;

Per rimodellare i dati, trasformandoli in formato long, possiamo utilizzare il comando <b>reshape</b>, in questo modo:

[code]
sonno.long <- reshape(sonno.wide, varying=3:5, v.names="ore",
                      timevar="tempo", direction="long")
&#91;/code&#93;

La funzione reshape ha tanti argomenti che possono essere manipolati, io qui ho sfruttato giusto i principali. L'argomento <b>varying</b> richiede di specificare quali sono le colonne che dovranno essere impilate, cioè quelle colonne che contengono i dati (le ore di sonno): tempo.0, tempo.30 e tempo.60. Io qui ho le ho indicate specificando il loro indice di colonna, ma avrei anche potuto passare, invece degli indici, un vettore contenente i nomi delle variabili. Come visto in precedenza, queste tre colonne sono in realtà un'unica variabile, che nel formato wide era stata suddivisa. Ora, nel formato long, a partire da queste tre colonne se ne dovrà ottenere una nuova che contiene i dati. Questa nuova colonna assumerà il nome specificato nell'argomento <b>v.names</b>. Inoltre, al dataset dovrà essere aggiunta una colonna che indica in quale tempo ogni dato è stato registrato; il nome che questa colonna dovrà assumere è stato indicato nell'argomento <b>timevar</b>. Infine, bisogna esplicitare che il dataset dovrà essere convertito in formato long e questo viene dichiarato attraverso l'argomento <b>direction</b>.

Possiamo vedere di seguito un'anteprima del risultato:

[code]
> sonno.long[1:10,]
     sogg tratt tempo ore id
1.1     1    PT     1 5.6  1
2.1     2    PT     1 4.8  2
3.1     3    PT     1 3.9  3
4.1     4    PT     1 5.8  4
5.1     5    PT     1 3.5  5
6.1     6    FT     1 3.9  6
7.1     7    FT     1 4.1  7
8.1     8    FT     1 5.0  8
9.1     9    FT     1 4.0  9
10.1   10    FT     1 4.0 10

Da long a wide


Costruiamo in R la tabella di dati in formato long:

sonno.long <- data.frame(
    sogg = factor(c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10)),
    tempo = factor(c(0,30,60,0,30,60,0,30,60,0,30,60,0,30,60,0,30,60,0,30,60,0,30,60,0,30,60,0,30,60)),
    tratt = c("PT","PT","PT","PT","PT","PT","PT","PT","PT","PT","PT","PT","PT","PT","PT",
        "FT","FT","FT","FT","FT","FT","FT","FT","FT","FT","FT","FT","FT","FT","FT"),
    ore = c(5.6,3.3,8.9,4.8,4.7,7.9,3.9,5.3,8.5,5.8,4.5,8.2,3.5,3.7,6.9,
        3.9,4.7,7,4.1,4.9,5.6,5,3.8,5.3,4,4.7,5.3,4,4.8,6.3)
)
&#91;/code&#93;

Usiamo ora la funzione reshape:

&#91;code&#93;
sonno.wide <- reshape(sonno.long, v.names="ore", timevar="tempo",
                      idvar="sogg", direction="wide")
&#91;/code&#93;

Stavolta, con <b>v.names</b> ho specificato al comando reshape qual è la variabile da suddividere nelle colonne, e, attraverso <b>timevar</b>, ho indicato sulla base di quale variabile bisogna creare queste colonne; inoltre, ho dovuto indicare a <b>idvar</b> qual è la variabile che codifica per i soggetti. Infine, non dobbiamo dimenticarci di indicare a <b>direction</b> che dobbiamo trasformare i dati in formato wide.

Visualizziamo il risultato:

[code]
> sonno.wide
   sogg tratt ore.0 ore.30 ore.60
1     1    PT   5.6    3.3    8.9
4     2    PT   4.8    4.7    7.9
7     3    PT   3.9    5.3    8.5
10    4    PT   5.8    4.5    8.2
13    5    PT   3.5    3.7    6.9
16    6    FT   3.9    4.7    7.0
19    7    FT   4.1    4.9    5.6
22    8    FT   5.0    3.8    5.3
25    9    FT   4.0    4.7    5.3
28   10    FT   4.0    4.8    6.3

Suddivisione dei dati


Quando i dati sono in formato long, talvolta può essere comodo spezzare il dataset in più oggetti a seconda del livello di una variabile. Per esempio, potremmo avere l’esigenza di suddividere i dati delle persone trattate con psicoterapia da quelli delle persone trattate con terapia farmacologica, magari per creare dei grafici separati per ogni gruppo. Questa operazione può essere realizzata molto facilmente attraverso il comando split:

sonno.split <- split(sonno.long, f=sonno.long$tratt)
&#91;/code&#93;

Il comando richiede, oltre al dataset, la variabile da utilizzare come criterio per la suddivisione (che nell'esempio è la colonna <i>tratt</i>). Come risultato, avremo un oggetto di tipo lista con due slot, uno per ogni livello della variabile <i>tratt</i>.

Per estrarre i dati di ogni slot, possiamo usare il dollaro, per esempio:

[code]
> sonno.split$FT
   sogg tempo tratt ore
16    6     0    FT 3.9
17    6    30    FT 4.7
18    6    60    FT 7.0
19    7     0    FT 4.1
20    7    30    FT 4.9
21    7    60    FT 5.6
22    8     0    FT 5.0
23    8    30    FT 3.8
24    8    60    FT 5.3
25    9     0    FT 4.0
26    9    30    FT 4.7
27    9    60    FT 5.3
28   10     0    FT 4.0
29   10    30    FT 4.8
30   10    60    FT 6.3

Per chi volesse divertirsi, ci sono due pacchetti, reshape e reshape2, che permettono di andare ben oltre quanto presentato in questo post. Qui l’articolo di presentazione dell’autore dei pacchetti.

Print Friendly, PDF & Email
Print Friendly, PDF & Email

Lascia un commento