Vorrei utilizzare la funzione mutate_if()
di dplyr per convertire le colonne di elenco in colonne di frame di dati, ma si verifica un errore enigmatico quando provo a fare così. Sto usando dplyr 0.5.0, purrr 0.2.2, R 3.3.0.Muting di colonne di un frame di dati basato su una funzione di predicato (dplyr :: mutate_if)
La configurazione di base assomiglia a questo: ho un frame di dati d
, alcuni dei cui colonne sono liste:
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]
)
Vorrei convertire la colonna di liste (in questo caso, d$A
) per un colonna del frame di dati utilizzando la seguente funzione:
tblfy <- function(x) {
x %>%
purrr::transpose() %>%
purrr::simplify_all() %>%
dplyr::as_data_frame()
}
Cioè, vorrei la lista colonne d$A
per essere sostituito da lista lapply(d$A, tblfy)
, che è
[[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
Naturalmente, in questo semplice caso, potrei semplicemente effettuare una semplice riassegnazione. Il punto, tuttavia, è che mi piacerebbe farlo a livello di programmazione, idealmente con dplyr, in un modo generalmente applicabile che potrebbe trattare qualsiasi numero di colonne di elenchi.
Ecco dove inciampo: Quando provo a convertire l'elenco colonne di data-frame-colonne utilizzando la seguente applicazione
d %>% dplyr::mutate_if(is.list, funs(tblfy))
ricevo un messaggio di errore che non so come interpretare:
Error: Each variable must be named.
Problem variables: 1, 2
Perché mutate_if()
falliscono? Come posso applicarlo correttamente per ottenere il risultato desiderato?
Osservazione
Un commentatore ha osservato che la funzione tblfy()
dovrebbe essere vettorializzato. Questo è un suggerimento ragionevole. Ma - a meno che non abbia vettorializzato in modo errato - non sembra che si arrivi alla radice del problema. Inserendo un vettorizzati versione del tblfy()
,
tblfy_vec <- Vectorize(tblfy)
in mutate_if()
fallisce con l'errore
Error: wrong result size (4), expected 2 or 1
Aggiornamento
Dopo aver acquisito una certa esperienza con purrr, ora trovo il seguente approccio naturale, se un po 'prolisso:
d %>%
map_if(is.list, ~ map(., ~ map_df(., identity))) %>%
as_data_frame()
Questo è più o meno identico alla soluzione di @ alistaire, di seguito, ma utilizza map_if()
, risp. map()
, al posto di mutate_if()
, risp. Vectorize()
.
Quindi, qual è esattamente l'output previsto? Vuoi cambiare A da un elenco di elenchi a un elenco di tibbles? – MrFlick
La funzione non è vettorizzata, accetta solo una lista. Guarda 'tblfy (d $ A)'. C'è un errore perché ci sono due liste in 'd $ A'. Non stai confrontando le mele con le mele. Nel tuo 'lapply (d $ A, tblfy)' stai dando alla tua funzione una lista alla volta, ecco perché funziona. 'tblfy (d $ A [[1]])' e 'tblfy (d $ A [[2]])'. Nella tua funzione dplyr stai fornendo due liste. Cambia 'tblfy' per accettare più di una lista, o cambia la chiamata dplyr. O come chiede MrFlick, pensa più in generale a quello che stai costruendo. –
@MrFlick Ho modificato la domanda per rendere esplicito l'output desiderato. È chiaro ora? – egnha