R Language
Omforma data mellan långa och breda former
Sök…
Introduktion
I R lagras tabelldata i dataramar . Detta ämne täcker olika sätt att transformera en enda tabell.
Anmärkningar
Omformningsfunktionen
Den mest flexibla bas R-funktionen för omformning av data är reshape
. Se ?reshape
för dess syntax.
# 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
Observera att data.frame är obalanserad, det vill säga enhet 2 saknar en observation under den första perioden, medan enheterna 3 och 4 saknas observationer under den andra perioden. Observera också att det finns två variabler som varierar under perioderna: räkningar och värden och två som inte varierar: identifierare och plats.
Lång till bred
För att omforma data.frame till bredformat,
# 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
Observera att de saknade tidsperioderna är fyllda med NA: er.
När vi omformar bredt anger "v.names" -argumentet kolumnerna som varierar över tiden. Om platsvariabeln inte är nödvändig kan den släppas innan omformningen med "släpp" -argumentet. När man släpper den enda icke-varierande / icke-id-kolumnen från data.frame blir argumentet v.names onödigt.
reshape(df, idvar="identifier", timevar="period", direction="wide",
drop="location")
Bred till lång
För att omforma länge med den nuvarande df.wide är en minimal syntax
reshape(df.wide, direction="long")
Men detta är vanligtvis svårare:
# 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))])
Nu kommer den enkla syntaxen att ge ett fel om odefinierade kolumner.
Med kolumnnamn som är svårare för reshape
att automatiskt analysera är det ibland nödvändigt att lägga till det "varierande" argumentet som berättar reshape
att gruppera specifika variabler i brett format för omvandlingen till långt format. Detta argument tar en lista över vektorer med variabla namn eller index.
reshape(df.wide, idvar="identifier",
varying=list(c(3,5,7), c(4,6,8)), direction="long")
Vid lång omformning kan argumentet "v.names" tillhandahållas för att byta namn på de resulterande varierande variablerna.
Ibland kan specifikationen av "varierande" undvikas genom att använda "sep" -argumentet som berättar reshape
vilken del av variabelnamnet som specificerar värdesargumentet och vilket specificerar tidsargumentet.
Omforma data
Ofta kommer data i tabeller. I allmänhet kan man dela upp denna tabellinformation i breda och långa format. I ett brett format har varje variabel sin egen kolumn.
Person | Höjd (cm] | Ålder [yr] |
---|---|---|
Alison | 178 | 20 |
Guppa | 174 | 45 |
Carl | 182 | 31 |
Ibland är det emellertid mer bekvämt att ha ett långt format, där alla variabler finns i en kolumn och värdena finns i en andra kolumn.
Person | Variabel | Värde |
---|---|---|
Alison | Höjd (cm] | 178 |
Guppa | Höjd (cm] | 174 |
Carl | Höjd (cm] | 182 |
Alison | Ålder [yr] | 20 |
Guppa | Ålder [yr] | 45 |
Carl | Ålder [yr] | 31 |
Base R, såväl som tredjepartspaket kan användas för att förenkla denna process. För vart och ett av alternativen kommer mtcars
att användas. Som standard är detta dataset i ett långt format. För att paketen ska fungera sätter vi in radnamn som den första kolumnen.
mtcars # shows the dataset
data <- data.frame(observation=row.names(mtcars),mtcars)
Bas R
Det finns två funktioner i bas R som kan användas för att konvertera mellan brett och långt format: stack()
och unstack()
.
long <- stack(data)
long # this shows the long format
wide <- unstack(long)
wide # this shows the wide format
Dessa funktioner kan emellertid bli mycket komplicerade för fall med mer avancerad användning. Lyckligtvis finns det andra alternativ som använder tredjepartspaket.
Tidyrpaketet
Detta paket använder gather()
att konvertera från bred till lång och spread()
att konvertera från lång till bred.
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)
Paketet data.table
Paketet data.table förlänger reshape2
funktionerna och använder funktionssmältan melt()
att gå från bred till lång och dcast()
att gå från lång till bred.
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)