5

I have a nested list that looks like this:

mylist <- vector("list", 2)
mylist[[1]]$name <- "The Tucson IOT Meetup Group"
mylist[[1]]$state <- "AZ"
mylist[[2]]$name <- "#SFMySQL Meetup"
mylist[[2]]$state <- "CA"

mylist
[[1]]
[[1]]$name
[1] "The Tucson IOT Meetup Group"

[[1]]$state
[1] "AZ"


[[2]]
[[2]]$name
[1] "#SFMySQL Meetup"

[[2]]$state
[1] "CA"

I'd like to turn this into a data frame with columns "name" and "state" and two rows, one for each record. But when I try to use as.data.frame to do this, I get back a single row of data, with separate columns for each of the records' variables, like this:

myframe <- as.data.frame(mylist)
myframe
                              name state          name.1 state.1
1 The Tucson IOT Meetup Group    AZ #SFMySQL Meetup      CA

I'm not sure what's happening. What's the right way to do this?

Jaap
  • 81,064
  • 34
  • 182
  • 193
Traviskorte
  • 113
  • 8

2 Answers2

6
do.call(rbind.data.frame, mylist)
##                           name state
## 2  The Tucson IOT Meetup Group    AZ
## 21             #SFMySQL Meetup    CA

The do.call function is somewhat like the (l/s)apply functions and allows functions to accumulate results of successive calls. The Reduce function sometimes accomplishes the same result:

 Reduce(rbind.data.frame, mylist)
##                          name state
##2  The Tucson IOT Meetup Group    AZ
##21             #SFMySQL Meetup    CA

You can even get rbind to "work" with Reduce:

Reduce(rbind, mylist)
##     name                          state
##init "The Tucson IOT Meetup Group" "AZ" 
##     "#SFMySQL Meetup"             "CA" 

Initially thought that may be the best result. (I prefer results that deliver character values rather than factors.) However, both Reduce approaches deliver rather strange structures when viewed with str().

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • That certainly works. What's do.call doing? Why wouldn't rbind(mylist) work? – Traviskorte Sep 21 '14 at 19:33
  • 1
    `mylist` is not a vector or matrix so `rbind.default` doesn't work and there is no `rbind.list` – IRTFM Sep 21 '14 at 19:42
  • The resulting ``row.names`` are strange (21 in the above), but I suppose this is harmless and, moreover, we can always ``NULL``ify them... – PatrickT Oct 01 '17 at 16:35
4

Or try data.tables rbindlist function (very efficient for big data sets)

library(data.table)
rbindlist(mylist)
#                           name state
# 1: The Tucson IOT Meetup Group    AZ
# 2:             #SFMySQL Meetup    CA
David Arenburg
  • 91,361
  • 17
  • 137
  • 196