R Language
Rimodellamento dei dati tra forme lunghe e larghe
Ricerca…
introduzione
In R, i dati tabulari sono memorizzati in frame di dati . Questo argomento copre i vari modi di trasformare una singola tabella.
Osservazioni
Pacchetti utili
- Rimodellamento, impilamento e divisione con data.table
- Rimodellare usando tidyr
- splitstackshape
La funzione di risagoma
La funzione R di base più flessibile per la risagoma dei dati viene reshape
. Vedi ?reshape
per la sua sintassi.
# create unbalanced longitudinal (panel) data set
set.seed(1234)
df <- data.frame(identifier=rep(1:5, each=3),
location=rep(c("up", "down", "left", "up", "center"), each=3),
period=rep(1:3, 5), counts=sample(35, 15, replace=TRUE),
values=runif(15, 5, 10))[-c(4,8,11),]
df
identifier location period counts values
1 1 up 1 4 9.186478
2 1 up 2 22 6.431116
3 1 up 3 22 6.334104
5 2 down 2 31 6.161130
6 2 down 3 23 6.583062
7 3 left 1 1 6.513467
9 3 left 3 24 5.199980
10 4 up 1 18 6.093998
12 4 up 3 20 7.628488
13 5 center 1 10 9.573291
14 5 center 2 33 9.156725
15 5 center 3 11 5.228851
Si noti che data.frame è sbilanciato, cioè all'unità 2 manca un'osservazione nel primo periodo, mentre le unità 3 e 4 mancano delle osservazioni nel secondo periodo. Inoltre, si noti che ci sono due variabili che variano nei periodi: conteggi e valori e due che non variano: identificatore e posizione.
Da lungo a largo
Per rimodellare il data.frame nel formato wide,
# reshape wide on time variable
df.wide <- reshape(df, idvar="identifier", timevar="period",
v.names=c("values", "counts"), direction="wide")
df.wide
identifier location values.1 counts.1 values.2 counts.2 values.3 counts.3
1 1 up 9.186478 4 6.431116 22 6.334104 22
5 2 down NA NA 6.161130 31 6.583062 23
7 3 left 6.513467 1 NA NA 5.199980 24
10 4 up 6.093998 18 NA NA 7.628488 20
13 5 center 9.573291 10 9.156725 33 5.228851 11
Si noti che i periodi di tempo mancanti sono compilati con NA.
In rimodellamento ampio, l'argomento "v.names" specifica le colonne che variano nel tempo. Se la variabile posizione non è necessaria, può essere eliminata prima di rimodellare con l'argomento "rilascia". Eliminando l'unica colonna non-variant / non-id da data.frame, l'argomento v.names diventa inutile.
reshape(df, idvar="identifier", timevar="period", direction="wide",
drop="location")
Da largo a lungo
Per rimodellare a lungo con l'attuale df.wide, c'è una sintassi minima
reshape(df.wide, direction="long")
Tuttavia, questo è in genere più complicato:
# remove "." separator in df.wide names for counts and values
names(df.wide)[grep("\\.", names(df.wide))] <-
gsub("\\.", "", names(df.wide)[grep("\\.", names(df.wide))])
Ora la sintassi semplice produrrà un errore sulle colonne non definite.
Con i nomi di colonna che sono più difficili per la reshape
funzione per analizzare automaticamente, a volte è necessario aggiungere l'argomento "variare", che racconta reshape
per raggruppare particolari variabili in grande formato per la trasformazione in formato esteso. Questo argomento prende una lista di vettori di nomi di variabili o indici.
reshape(df.wide, idvar="identifier",
varying=list(c(3,5,7), c(4,6,8)), direction="long")
In rimodellamento lungo, è possibile fornire l'argomento "v.names" per rinominare le variabili variabili risultanti.
A volte la specifica di "variabile" può essere evitata usando l'argomento "sep" che dice reshape
quale parte del nome della variabile specifica l'argomento value e che specifica l'argomento time.
Rimodellamento dei dati
Spesso i dati arrivano nelle tabelle. Generalmente si possono dividere questi dati tabulari in formati ampi e lunghi. In un ampio formato, ogni variabile ha una propria colonna.
Persona | Altezza (cm] | Età [anno] |
---|---|---|
Alison | 178 | 20 |
peso | 174 | 45 |
Carl | 182 | 31 |
Tuttavia, a volte è più conveniente disporre di un formato lungo, in cui tutte le variabili si trovano in una colonna e i valori si trovano in una seconda colonna.
Persona | Variabile | Valore |
---|---|---|
Alison | Altezza (cm] | 178 |
peso | Altezza (cm] | 174 |
Carl | Altezza (cm] | 182 |
Alison | Età [anno] | 20 |
peso | Età [anno] | 45 |
Carl | Età [anno] | 31 |
Base R, così come pacchetti di terze parti possono essere utilizzati per semplificare questo processo. Per ognuna delle opzioni, verrà utilizzato il set di dati mtcars
. Per impostazione predefinita, questo set di dati è in un formato lungo. Per far funzionare i pacchetti, inseriremo i nomi delle righe come prima colonna.
mtcars # shows the dataset
data <- data.frame(observation=row.names(mtcars),mtcars)
Base R
Ci sono due funzioni nella base R che possono essere usate per convertire tra il formato wide e long: stack()
e unstack()
.
long <- stack(data)
long # this shows the long format
wide <- unstack(long)
wide # this shows the wide format
Tuttavia, queste funzioni possono diventare molto complesse per casi d'uso più avanzati. Fortunatamente, ci sono altre opzioni che usano pacchetti di terze parti.
Il pacchetto tidyr
Questo pacchetto usa gather()
per convertire da wide a long e spread()
per convertire da long a wide.
library(tidyr)
long <- gather(data, variable, value, 2:12) # where variable is the name of the
# variable column, value indicates the name of the value column and 2:12 refers to
# the columns to be converted.
long # shows the long result
wide <- spread(long,variable,value)
wide # shows the wide result (~data)
Il pacchetto data.table
Il pacchetto data.table estende le funzioni di reshape2
e usa la funzione melt()
per passare da wide a long e dcast()
per passare da long a wide.
library(data.table)
long <- melt(data,'observation',2:12,'variable', 'value')
long # shows the long result
wide <- dcast(long, observation ~ variable)
wide # shows the wide result (~data)