Chciałbym użyć funkcji dplyr mutate_if()
do konwertowania kolumn list do kolumn-ramek danych, ale napotkasz dziwny błąd, gdy próbuję Zrób tak. Używam dplyr 0.5.0, purrr 0.2.2, R 3.3.0.Mutowanie kolumn ramki danych na podstawie funkcji predykatu (dplyr :: mutate_if)
Podstawowa konfiguracja wygląda następująco: Mam ramki danych d
, którego niektóre kolumny są wykazy:
d <- dplyr::data_frame(
A = list(
list(list(x = "a", y = 1), list(x = "b", y = 2)),
list(list(x = "c", y = 3), list(x = "d", y = 4))
),
B = LETTERS[1:2]
)
chciałbym przekonwertować kolumnę list (w tym przypadku d$A
) do gniazda kolumna ramek danych z następującą funkcję:
tblfy <- function(x) {
x %>%
purrr::transpose() %>%
purrr::simplify_all() %>%
dplyr::as_data_frame()
}
oznacza to, że ja jak lista odbierającej d$A
być zastąpiony wykazem lapply(d$A, tblfy)
, która
[[1]]
# A tibble: 2 x 2
x y
<chr> <dbl>
1 a 1
2 b 2
[[2]]
# A tibble: 2 x 2
x y
<chr> <dbl>
1 c 3
2 d 4
Oczywiście w tym prostym przypadku mógłbym po prostu dokonać prostego przypisania. Chodzi jednak o to, że chciałbym to zrobić programowo, najlepiej za pomocą dplyr, w ogólnie obowiązujący sposób, który mógłby zająć się dowolną liczbą kolumn z listy.
Oto gdzie potykam: Kiedy próbuję przekonwertować listy-kolumn z danymi-Frame-kolumn stosując następującą aplikację
d %>% dplyr::mutate_if(is.list, funs(tblfy))
otrzymuję komunikat o błędzie, że nie wiem jak interpretować:
Error: Each variable must be named.
Problem variables: 1, 2
Dlaczego mutate_if()
nie? Jak mogę go właściwie zastosować, aby uzyskać pożądany rezultat?
Uwaga
commenter wskazał, że funkcja tblfy()
należy wektorowy. To rozsądna sugestia. Ale - o ile nie mam wektoryzacji niepoprawnie - nie wydaje się, aby znalazło się u źródła problemu. Podłączając vectorized wersja tblfy()
,
tblfy_vec <- Vectorize(tblfy)
do mutate_if()
nie powiedzie się z powodu błędu
Error: wrong result size (4), expected 2 or 1
aktualizacji
Po zdobyciu pewnego doświadczenia z Purrr, teraz znalazły się następujące podejście naturalne, jeśli jest nieco przewlekły:
d %>%
map_if(is.list, ~ map(., ~ map_df(., identity))) %>%
as_data_frame()
To jest mniej lub bardziej identyczne z rozwiązaniem @ alistaire, poniżej, ale używa map_if()
, odp. map()
, zamiast mutate_if()
, wzgl. Vectorize()
.
Czym dokładnie jest oczekiwany wynik? Chcesz zmienić A z listy list na listę przekąsek? – MrFlick
Twoja funkcja nie jest wektoryzowana, przyjmuje tylko jedną listę. Spójrz na 'tblfy (d $ A)'. Wystąpił błąd, ponieważ istnieją dwie listy w 'd $ A'. Nie porównujesz jabłek do jabłek. W twoim 'lapply (d $ A, tblfy)' nadajesz swojej funkcji jedną listę na raz, dlatego to działa. 'tblfy (d $ A [[1]])' i 'tblfy (d $ A [[2]])'. W twojej funkcji dplyr dostarczasz dwie listy. Zmień 'tblfy', aby zaakceptować więcej niż jedną listę, lub zmień wywołanie dplyr. Lub jak pyta MrFlick, szerzej myśl o tym, co budujesz. –
@MrFlick Dokonałem edycji pytania, aby uzyskać pożądany wynik. Czy teraz jest jasne? – egnha