2015-08-17 18 views
10

Ho una lista di elenchi con nome della seguente modulo da un oggetto JSON:lista di liste con nome per data.frame

my_list = list(list(a = 10, b = "blah"), 
       list(a = 15, b = "stuff")) 

Ogni elemento della lista esterna è una lista di nome e voglio convertirlo ad una data.frame del seguente modulo con i nomi delle colonne intatte:

a b 
10 "blah" 
15 "stuff" 

in superficie, posso realizzare questo facendo to_df = data.frame(do.call(rbind, my_list)).

Tuttavia, se dovessi cercare di estrarre una singola colonna utilizzando to_df$a o to_df[,1] vorrei avere un elenco invece di un vettore come normalmente ci si aspetta da un data.frame:

> to_df[,1] 
[[1]] 
[1] 10 

[[2]] 
[1] 15 

Invece di:

> to_df[,1] 
[1] 10 15 

Un vecchio post sulla mailing list di R ha suggerito la seguente soluzione: to_df = as.data.frame(t(sapply(my_list, rbind))). Ma non solo non trasferisce i nomi delle colonne, ma ha lo stesso problema di restituire una lista invece di un vettore quando si guardano le singole colonne usando to_df[,1].

Qual è il modo migliore per raggiungere questo obiettivo? Esiste un modo dplyr?

EDIT: Grazie per tutte le soluzioni, sembra che il trucco è quello di lapply e trasformare ogni elemento della lista per un data.frame e poi legarli insieme utilizzando dplyr o do.call. In alternativa, data.table esegue la maggior parte del lavoro con una singola chiamata a rbindlist.

+4

Si potrebbe provare 'lapply (my_list, data.frame)%>% bind_rows()' –

+1

Sono disponibili diverse soluzioni praticabili sotto. Ma dovresti notare che 'to_df = data.frame (do.call (rbind, my_list))' non sembra darti un 'data.frame'. Sembra darti un 'elenco' basato sull'output che mostri. –

risposta

10

Preferisco rbindlist dal pacchetto data.table. È semplice, veloce e restituisce un frame/tabella dati.

data.table::rbindlist(my_list) 
#  a  b 
# 1: 10 blah 
# 2: 15 stuff 

Un altro vantaggio è che rbindlist() riempirà automaticamente i valori mancanti con NA.

Per rimuovere la classe data.table, si può semplicemente avvolgere in as.data.frame()

as.data.frame(data.table::rbindlist(my_list)) 
6

In base di R si può fare

df<-do.call(rbind,lapply(my_list,data.frame)) 
5

Sembra che si può fare questo con bind_rows dalla versione di sviluppo di dplyr, dplyr_0.4.2.9002, a partire da due giorni fa.

library(dplyr) 
bind_rows(my_list) 

Source: local data frame [2 x 2] 

    a  b 
1 10 blah 
2 15 stuff