Richard Herron
Richard Herron

Reputation: 10092

Convert list of lists of vectors to data frame in R

I have a list of lists of numeric vectors. I would like to

  1. sum each vector
  2. make each inner list of scalars into a vector
  3. combine the vectors into one data frame where the vectors are rows

I hacked together the following, but it seems that this is very clumsy and not the R way. I suspect that if I use rapply and four steps that I am doing something wrong (not in terms of results, but in terms of efficiency and understanding). Is there a right way to do this operation?

dat1 <- list(list(1:2, 3:4), list(5:6, 7:8))
dat2 <- rapply(dat1, sum, how="list") 
dat3 <- lapply(dat2, unlist)
dat4 <- do.call(rbind, dat3)
dat5 <- data.frame(dat4)

So the desired output is

> dat5
  X1 X2
1  3  7
2 11 15
> class(dat5)
[1] "data.frame"

Upvotes: 4

Views: 1333

Answers (2)

Rich Scriven
Rich Scriven

Reputation: 99331

This seems to get you there in one go, without much difference in efficiency from using matrix

> as.data.frame(do.call(rbind, rapply(dat1, sum, how = "list")))
#   X1 X2
# 1  3  7
# 2 11 15

> f1 <- function() 
      as.data.frame(matrix(rapply(dat1,sum), nrow=length(dat1), byrow=TRUE))
> f2 <- function() 
      as.data.frame(do.call(rbind, rapply(dat1, sum, how = "list")))
> library(microbenchmark)
> microbenchmark(f1(), f2())
# Unit: microseconds
#  expr    min      lq median       uq     max neval
#  f1() 91.047 92.7105  93.94 102.2855 199.305   100
#  f2() 95.213 97.3150  98.43 101.8240 134.403   100

Almost a wash for this example.

Upvotes: 3

tim riffe
tim riffe

Reputation: 5691

Well, I'm not sure if it's any more efficient, but here's something similar:

as.data.frame(matrix(rapply(dat1,sum), nrow=length(dat1), byrow=TRUE))
X1 X2
1  3  7
2 11 15

Upvotes: 3

Related Questions