Mam zagnieżdżoną listę danych. Jego długość wynosi 132, a każdy element jest listą o długości 20. Czy istnieje szybki sposób na przekształcenie tej struktury w ramkę danych, która ma 132 wiersze i 20 kolumn danych?
Oto kilka przykładowych danych do pracy:
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
Odpowiedzi:
Zakładając, że twoja lista list nazywa się
l
:Powyższe przekształci wszystkie kolumny znaków w czynniki, aby tego uniknąć, możesz dodać parametr do wywołania data.frame ():
źródło
Z
rbind
Edit: Poprzednia wersja powrót
data.frame
zlist
„s zamiast wektorów (jak @IanSudbery zauważył w komentarzach).źródło
rbind(your_list)
zwraca macierz list 1x32?do.call
przekazuje elementyyour_list
argumentów jakorbind
. Jest to odpowiednikrbind(your_list[[1]], your_list[[2]], your_list[[3]], ....., your_list[[length of your_list]])
.your_list
zawierały wektory o jednakowych rozmiarach.NULL
ma długość 0, więc powinno się nie powieść.Możesz skorzystać z
plyr
pakietu. Na przykład zagnieżdżona lista formularzama teraz długość 4, a każda lista
l
zawiera kolejną listę o długości 3. Teraz możesz uruchomići powinien uzyskać taki sam wynik jak w odpowiedzi @Marek i @nico.
źródło
matrix
podejściem.data.frame(t(sapply(mylistlist,c)))
sapply
konwertuje go na macierz.data.frame
konwertuje macierz na ramkę danych.źródło
c
tutaj odegrać, jedno wystąpienie danych z listy? Och, czekaj, c dla funkcji konkatenacji, prawda? Zagubienie się przy użyciu c. @ Mnel Zgadzam się również z @dchandler, poprawienie nazw kolumn było cenną potrzebą w moim przypadku użycia. Genialne rozwiązanie.?c
:Combine Values into a Vector or List
Załóżmy, że twoja lista się nazywa
L
,źródło
data.frame(Reduce(rbind, list(c('col1','col2'))))
tworzy ramkę danych z 2 wierszami, 1 kolumną (spodziewałem się 1 rzędu 2 kolumn)Pakiet
data.table
ma funkcjęrbindlist
superszybkiej implementacjido.call(rbind, list(...))
.To może trwać listę
lists
,data.frames
lubdata.tables
jako wejście.Zwraca
data.table
dziedziczenie zdata.frame
.Jeśli naprawdę chcesz przekonwertować z powrotem na data.frame użyj
as.data.frame(DT)
źródło
setDF
teraz pozwala powrócić do data.frame przez odniesienie.tibble
Opakowanie ma funkcjęenframe()
, która rozwiązuje ten problem przez zmuszanie zagnieżdżonychlist
obiektów zagnieżdżonytibble
( „uporządkowane” ramki danych) obiektów. Oto krótki przykład z R dla Data Science :Ponieważ na liście znajduje się kilka gniazd
l
, możesz użyć przyciskuunlist(recursive = FALSE)
do usunięcia niepotrzebnego zagnieżdżenia, aby uzyskać tylko jedną hierarchiczną listę, a następnie przejść do niejenframe()
. Używamtidyr::unnest()
do odczekania danych wyjściowych w jednopoziomowej „uporządkowanej” ramce danych, która zawiera dwie kolumny (jedną dla grupyname
i jedną dla obserwacji z grupamivalue
). Jeśli chcesz, aby kolumny były szerokie, możesz dodać kolumnę,add_column()
która po prostu powtarza kolejność wartości 132 razy. Następnie tylkospread()
wartości.źródło
W zależności od struktury list istnieje kilka
tidyverse
opcji, które działają dobrze z listami o nierównej długości:Możesz także mieszać wektory i ramki danych:
źródło
X2
nie można przekonwertować z liczby całkowitej na znakReshape2 daje taką samą wydajność jak w powyższym przykładzie plyr:
daje:
Jeśli były niemal z pikseli ty mógł to wszystko zrobić w 1 linii w / przekształcenia ().
źródło
Ta metoda używa
tidyverse
pakietu ( mruczenie ).Lista:
Przekształcanie go w ramkę danych (a
tibble
dokładniej):źródło
Rozszerzając odpowiedź @ Marka: jeśli chcesz uniknąć zamiany łańcuchów na czynniki, a wydajność nie stanowi problemu, spróbuj
źródło
Dla ogólnego przypadku głęboko zagnieżdżonych list z 3 lub więcej poziomami, takimi jak te uzyskane z zagnieżdżonego JSON:
rozważ
melt()
najpierw podejście do konwersji zagnieżdżonej listy do wysokiego formatu:po
dcast()
czym następuje przejście do uporządkowanego zestawu danych, w którym każda zmienna tworzy kolumnę, a każda obserwacja tworzy wiersz:źródło
Więcej odpowiedzi wraz z harmonogramem w odpowiedzi na to pytanie: Jaki jest najskuteczniejszy sposób na rzutowanie listy jako ramki danych?
Najszybszym sposobem, który nie tworzy ramki danych z listami zamiast wektorów dla kolumn wydaje się być (z odpowiedzi Martina Morgana):
źródło
Czasami twoje dane mogą być listą wektorów o tej samej długości.
(Wektory wewnętrzne mogą być również listami, ale upraszczam, aby ułatwić czytanie).
Następnie możesz wprowadzić następującą modyfikację. Pamiętaj, że możesz wylistować jeden poziom na raz:
Teraz użyj swojej ulubionej metody wymienionej w innych odpowiedziach:
źródło
Oto, co w końcu dla mnie zadziałało:
do.call("rbind", lapply(S1, as.data.frame))
źródło
źródło
W przypadku rozwiązania równoległego (wielordzeniowego, wielosesyjnego itp.) Używającego
purrr
rodziny rozwiązań użyj:Gdzie
l
jest lista.Aby przetestować najbardziej efektywne
plan()
, możesz użyć:źródło
Dla mnie zadziałało następujące proste polecenie:
Odniesienie ( odpowiedź Quora )
Ale to się nie powiedzie, jeśli nie jest oczywiste, jak przekonwertować listę na ramkę danych:
Uwaga : odpowiedź dotyczy tytułu pytania i może pomijać niektóre szczegóły pytania
źródło
Krótkim (ale być może nie najszybszym) sposobem na zrobienie tego byłoby użycie bazy r, ponieważ ramka danych jest tylko listą wektorów o jednakowej długości . Tak więc konwersja między twoją listą wejściową a 30 x 132 danymi. Ramka byłaby:
Stamtąd możemy przetransponować go na matrycę 132 x 30 i przekonwertować z powrotem na ramkę danych:
Jako jedna linijka:
Nazwy nazw będą dość denerwujące, ale zawsze możesz zmienić ich nazwy
rownames(new_df) <- 1:nrow(new_df)
źródło
Co powiesz na używanie
map_
funkcji razem zfor
pętlą? Oto moje rozwiązanie:gdzie
map_dfr
przekonwertuj każdy element listy na data.frame, a następnie połączrbind
je całkowicie.W twoim przypadku myślę, że byłoby to:
źródło