31

I have a list of lists that looks like this: x[[state]][[year]]. Each element of this is a data frame, and accessing them individually is not a problem.

However, I'd like to rbind data frames across multiple lists. More specifically, I'd like to have as output as many dataframes as I have years, that is rbind all the state data frames within each year. In other words, I'd like to combine all my state data, year by year, into separate data frames.

I know that I can combine a single list into a data frame with do.call("rbind",list). But I don't know how I can do so across lists of lists.

1
  • 2
    Out of curiosity, why are you dealing with data this way rather than just having one large data frame with all the data? Commented Oct 30, 2009 at 22:41

3 Answers 3

52

Collapse it into a list first:

list <- unlist(listoflists, recursive = FALSE)
df <- do.call("rbind", list)
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the prompt help! But this isn't exactly what I want. Your answer gives me a SINGLE dataframe of all the data frames within the list of lists (using unlist, a cool command I never knew about). But I'd like a list of 32 rbind'ed data frames, which are as many years as I have, that combine all the states together. The first line of your answers gets me an approximately state * year length list (though for some reason I get length = 1584, not 32*50=1600 as I'd expect). So I think that's a clue...
After some more experimentation, I think I'm getting somewhere. I named the elements of the state list for the first time, so that now the elements of the unlisted list (after Hadley's first command) now have useful names like "AL3" and "TX4". Now I have to combine all the 3's together, all the 4's, and so forth.
Oh boy, I guess regular expressions are part of the answer then. I tried grep("1$",names(list)) to get the lists that are named with a "1" but that gets me all the years with a 1 in them, like 11, 21, 31. I tried grep("\D1$",names(list)) but no go.
You might try using melt from the reshape package - it will add in variables that will make things easier. One you have a single data frame, use split to break it into the pieces you want.
12

You can do something along the following lines (I could not test as I have no such structure):

extract.year <- function(my.year) lapply(x, function(y) y[[my.year]])

x.by.year <- sapply(my.list.of.years, function(my.year)
    do.call(rbind, extract.year(my.year)))   

The function extract year creates a list containing just the dataframes for the given year. Then you rbind them...

2 Comments

Things were getting complicated with the answer above, so I tried your approach, which worked! With a little modification. The first line returned the dataframe I was looking for. The second line didn't work, so instead I turned to Hadley's plyr package. This command returns a list of rbinded dataframes perfectly after your first line: llply(my.list.of.years, function(my.year) do.call( rbind, extract.year(my.year))) Awesome, thanks guys for helping!
ldply() is even faster and more efficient!
0

I realize I'm a bit late to the party, but what about:

mymat <- do.call(rbind, lapply(mylist, function(element){
  element[[1]] # if df is the 1st entry of each list, could also access by name
}))
mydf <- as.data.frame(mymat)

It looks similar to the response of Marek, but avoids the sapply/lapply combo.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.