Mam problem z przestawieniem następującej ramki danych:
set.seed(45)
dat1 <- data.frame(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dat1
name numbers value
1 firstName 1 0.3407997
2 firstName 2 -0.7033403
3 firstName 3 -0.3795377
4 firstName 4 -0.7460474
5 secondName 1 -0.8981073
6 secondName 2 -0.3347941
7 secondName 3 -0.5013782
8 secondName 4 -0.1745357
Chcę go przekształcić, tak aby każda unikalna zmienna „name” była nazwą, z „wartościami” jako obserwacjami wzdłuż tego wiersza i „liczbami” jako nazwami kolumn. Coś w stylu:
name 1 2 3 4
1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
Sprawdziliśmy melt
i cast
i kilka innych rzeczy, ale nie wydaje się, aby wykonać zadanie.
Odpowiedzi:
Korzystanie z
reshape
funkcji:źródło
reshape
pochodzi zstats
. Nie wspominając o tym, że jest szybszy! =)reshape
jest znakomitym przykładem okropnej funkcji API. Jest bardzo blisko bezużyteczne.reshape
komentarze i podobne nazwy argumentów nie są takie pomocne. Odkryłem jednak, że od długiego do szerokiego musisz podaćdata =
swoje dane. Ramka,idvar
= zmienna, która identyfikuje twoje grupy,v.names
= zmienne, które staną się wieloma kolumnami w szerokim formacie,timevar
= zmienna zawierająca wartości, które zostaną dodane abyv.names
w szerokim formacie,direction = wide
isep = "_"
. Wystarczająco jasne? ;)Nowy
tidyr
pakiet (w 2014 r.) Również robi to po prostu, przy czymgather()
/spread()
oznacza warunkimelt
/cast
.Edit: Teraz, w 2019 roku, tidyr v 1.0 został uruchomiony i zestaw
spread
igather
na ścieżce amortyzację, preferując zamiastpivot_wider
apivot_longer
, który można znaleźć opisane w tej odpowiedzi . Czytaj dalej, jeśli chcesz rzucić okiem na krótkie życiespread/gather
.Z github ,
źródło
tidyr
ireshape2
. Dostarcza dobrych przykładów i wyjaśnień.Możesz to zrobić za pomocą
reshape()
funkcji lub za pomocą funkcjimelt()
/cast()
w pakiecie przekształcania. W przypadku drugiej opcji przykładowy kod toLub używając
reshape2
źródło
cast
lubdcast
nie będzie działać dobrze, jeśli nie masz wyraźnej kolumny „wartość”. Spróbuj,dat <- data.frame(id=c(1,1,2,2),blah=c(8,4,7,6),index=c(1,2,1,2)); dcast(dat, id ~ index); cast(dat, id ~ index)
a nie dostaniesz tego, czego oczekujesz. Musisz wyraźnie zanotowaćvalue/value.var
-cast(dat, id ~ index, value="blah")
idcast(dat, id ~ index, value.var="blah")
na przykład.Inną opcją, jeśli problemem jest wydajność, jest
data.table
rozszerzenie funkcjireshape2
melt & dcast( Odniesienie: Wydajne przekształcanie przy użyciu data.tables )
A od data.table v1.9.6 możemy rzutować na wiele kolumn
źródło
data.table
podejście jest najlepsze! bardzo wydajny ... zobaczysz różnicę, gdyname
jest kombinacja 30-40 kolumn !!Korzystając z przykładowej ramki danych, możemy:
źródło
Pozostałe dwie opcje:
Pakiet podstawowy:
sqldf
pakiet:źródło
ValCol <- unique(dat1$numbers);s <- sprintf("MAX(CASE WHEN numbers = %s THEN value ELSE NULL END) `%s`,", ValCol, ValCol);mquerym <- gsub('.{1}$','',paste(s, collapse = "\n"));mquery <- paste("SELECT name,", mquerym, "FROM dat1", "GROUP BY name", sep = "\n");sqldf(mquery)
Korzystanie z podstawowej
aggregate
funkcji R :źródło
W wersji deweloperskiej
tidyr
‘0.8.3.9000’
istniejepivot_wider
ipivot_longer
która jest uogólniona do przekształcania (odpowiednio długa -> szeroka, szeroka -> długa) od 1 do wielu kolumn. Korzystanie z danych PO-jedna kolumna długa -> szeroka
-> utworzył kolejną kolumnę do pokazania funkcjonalności
źródło
Funkcja podstawowa
reshape
działa idealnie:Gdzie
idvar
to kolumna klas oddzielająca wierszetimevar
to kolumna klas do szerokiego rzutowaniav.names
to kolumna zawierająca wartości liczbowedirection
określa szeroki lub długi formatsep
argument jest separatorem stosowanym międzytimevar
nazwami klas av.names
danymi wyjściowymidata.frame
.Jeśli nie
idvar
istnieje, utwórz go przed użyciemreshape()
funkcji:Pamiętaj tylko, że
idvar
jest to wymagane!timevar
Av.names
część jest łatwe. Wynik tej funkcji jest bardziej przewidywalny niż niektóre inne, ponieważ wszystko jest wyraźnie zdefiniowane.źródło
Jest bardzo mocny nowy pakiet z genialnych naukowców danych w Win-Vector (ludzi, które złożyły
vtreat
,seplyr
ireplyr
) o nazwiecdata
. Implementuje zasady „skoordynowanych danych” opisane w tym dokumencie, a także w tym poście na blogu . Chodzi o to, że niezależnie od sposobu organizacji danych, powinna istnieć możliwość identyfikacji poszczególnych punktów danych za pomocą systemu „współrzędnych danych”. Oto fragment ostatniego postu na blogu Johna Mounta:Najpierw zbudujemy tabelę kontrolną (szczegóły w poście na blogu ), a następnie przeprowadzimy przenoszenie danych z wierszy do kolumn.
źródło
o wiele łatwiejszy sposób!
jeśli chcesz wrócić z szerokiego na długi, zmień tylko Szeroki na Długi i żadnych zmian w obiektach.
źródło