R Language
Przekształcanie danych między długimi i szerokimi formularzami
Szukaj…
Wprowadzenie
W R dane tabelaryczne są przechowywane w ramkach danych . Ten temat obejmuje różne sposoby przekształcania pojedynczej tabeli.
Uwagi
Pomocne pakiety
- Przekształcanie, układanie w stosy i dzielenie za pomocą data.table
- Przekształć używając Tidyr
- splitstackshape
Funkcja zmiany kształtu
Najbardziej elastyczną podstawową funkcją R do przekształcania danych jest reshape
. Zobacz ?reshape
dla jego składni.
# 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
Należy zauważyć, że ramka data.frame jest niezrównoważona, to znaczy, jednostka 2 nie obserwuje obserwacji w pierwszym okresie, podczas gdy jednostki 3 i 4 brakuje obserwacji w drugim okresie. Należy również pamiętać, że istnieją dwie zmienne, które różnią się w poszczególnych okresach: liczby i wartości oraz dwie, które nie różnią się: identyfikator i lokalizacja.
Długa do szerokiej
Aby zmienić format data.frame na szeroki format,
# 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
Zauważ, że brakujące okresy są wypełnione NA.
Podczas szerokiego przekształcania argument „v.names” określa kolumny, które zmieniają się w czasie. Jeśli zmienna lokalizacji nie jest konieczna, można ją usunąć przed zmianą kształtu za pomocą argumentu „drop”. Po usunięciu jedynej niezmiennej / niezidentyfikowanej kolumny z data.frame argument v.names staje się niepotrzebny.
reshape(df, idvar="identifier", timevar="period", direction="wide",
drop="location")
Szeroki na długi
Aby długo zmieniać kształt przy użyciu bieżącego pliku df.wide, minimalna składnia to
reshape(df.wide, direction="long")
Jest to jednak zwykle trudniejsze:
# 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))])
Teraz prosta składnia spowoduje błąd dotyczący niezdefiniowanych kolumn.
W przypadku nazw kolumn, które są trudniejsze do automatycznego parsowania, funkcja reshape
czasami wymaga dodania argumentu „zmiennego”, który nakazuje reshape
grupowania określonych zmiennych w formacie szerokim w celu przekształcenia w format długi. Ten argument pobiera listę wektorów nazw lub indeksów zmiennych.
reshape(df.wide, idvar="identifier",
varying=list(c(3,5,7), c(4,6,8)), direction="long")
Przy długim przekształcaniu można podać argument „v.names”, aby zmienić nazwę wynikowych zmiennych zmiennych.
Czasami można uniknąć specyfikacji „zmiennego” za pomocą argumentu „sep”, który mówi reshape
która część nazwy zmiennej określa argument wartości, a która określa argument czasu.
Przekształcanie danych
Często dane są w tabelach. Zasadniczo dane tabelaryczne można podzielić na szerokie i długie formaty. W szerokim formacie każda zmienna ma własną kolumnę.
Osoba | Wzrost (cm] | Wiek [rok] |
---|---|---|
Alison | 178 | 20 |
Kok | 174 | 45 |
Carl | 182 | 31 |
Czasami jednak wygodniej jest mieć długi format, w którym wszystkie zmienne są w jednej kolumnie, a wartości w drugiej kolumnie.
Osoba | Zmienna | Wartość |
---|---|---|
Alison | Wzrost (cm] | 178 |
Kok | Wzrost (cm] | 174 |
Carl | Wzrost (cm] | 182 |
Alison | Wiek [rok] | 20 |
Kok | Wiek [rok] | 45 |
Carl | Wiek [rok] | 31 |
Aby uprościć ten proces, można użyć Base R, a także pakietów stron trzecich. Dla każdej z opcji zostanie mtcars
zestaw danych mtcars
. Domyślnie ten zestaw danych ma długi format. Aby pakiety działały, wstawimy nazwy wierszy jako pierwszą kolumnę.
mtcars # shows the dataset
data <- data.frame(observation=row.names(mtcars),mtcars)
Baza R
W bazie R znajdują się dwie funkcje, których można użyć do konwersji między szerokim a długim formatem: stack()
i unstack()
.
long <- stack(data)
long # this shows the long format
wide <- unstack(long)
wide # this shows the wide format
Funkcje te mogą jednak stać się bardzo złożone w przypadku bardziej zaawansowanych przypadków użycia. Na szczęście istnieją inne opcje korzystające z pakietów stron trzecich.
Pakiet Tidyr
Ten pakiet używa funkcji gather()
do konwersji z szerokiego na długi i spread()
do konwersji z długiego na szeroki.
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)
Pakiet data.table
Pakiet data.table rozszerza funkcje reshape2
i używa funkcji melt()
aby przejść z szerokiej na długą i dcast()
aby przejść z długiej do szerokiej.
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)