6

So I have a list, say:

L1 <- list(1:10, 5:14, 10:19)

Now I am trying to get the output of the list as dataframe such that my output looks:

 1. 1  2  3  4  5  6  7  8  9 10
 2. 5  6  7  8  9 10 11 12 13 14
 3. 10 11 12 13 14 15 16 17 18 19

I am using

as.data.frame(L1, row.names = TRUE)

and

list_vect2df(L1)

But none of them are giving the required output

Jilber Urbina
  • 58,147
  • 10
  • 114
  • 138
Ethan
  • 63
  • 1
  • 1
  • 6

4 Answers4

5

Here is an idea using t, as.data.frame, and map_dfr from the package.

L1 <- list(1:10, 5:14, 10:19)

library(purrr)

map_dfr(L1, ~as.data.frame(t(.x)))
#   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
# 1  1  2  3  4  5  6  7  8  9  10
# 2  5  6  7  8  9 10 11 12 13  14
# 3 10 11 12 13 14 15 16 17 18  19

The same idea but completely in base R.

do.call(rbind, lapply(L1, function(x) as.data.frame(t(x))))
#   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
# 1  1  2  3  4  5  6  7  8  9  10
# 2  5  6  7  8  9 10 11 12 13  14
# 3 10 11 12 13 14 15 16 17 18  19

Another base R idea that uses as.data.frame twice. We can change the row names later.

as.data.frame(t(as.data.frame(L1)))
#        V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
# X1.10   1  2  3  4  5  6  7  8  9  10
# X5.14   5  6  7  8  9 10 11 12 13  14
# X10.19 10 11 12 13 14 15 16 17 18  19

Finally, the same idea but use transpose function from the .

data.table::transpose(as.data.frame(L1))
#   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
# 1  1  2  3  4  5  6  7  8  9  10
# 2  5  6  7  8  9 10 11 12 13  14
# 3 10 11 12 13 14 15 16 17 18  19
www
  • 38,575
  • 12
  • 48
  • 84
5

You can unlist and use matrix, then converting to data.frame. It seems to be faster for this case.

as.data.frame(matrix(unlist(L1),nrow=length(L1),byrow=TRUE)

microbenchmark::microbenchmark(
a= map_dfr(L1, ~as.data.frame(t(.x))),
b= do.call(rbind, lapply(L1, function(x) as.data.frame(t(x)))),
c= as.data.frame(t(as.data.frame(L1))),
d= data.table::transpose(as.data.frame(L1)),
e= as.data.frame(matrix(unlist(L1),nrow=length(L1),byrow=TRUE)),
times = 100,unit = "relative")

# Unit: relative
# expr       min        lq      mean    median        uq       max neval
# a  9.146545  8.548656  8.859087  8.859051  9.449237  7.265274   100
# b 13.879833 11.523000 11.433790 10.924726 10.797251 24.012107   100
# c 12.719835 10.635809 10.442108 10.229913 10.259789  7.020377   100
# d 10.439881  9.143530  9.205734  8.859026  9.176125  6.624454   100
# e  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000   100
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
  • 1
    `b` returns error: `Error in rbind(deparse.level, ...) : numbers of columns of arguments do not match` – PM0087 Apr 22 '20 at 15:50
1

another purrr solution

purrr:::reduce(L1, rbind.data.frame) 

Using rbind instead gives a matrix.

Roman
  • 17,008
  • 3
  • 36
  • 49
-1

I have found a tool on rbloggers that is really helpful.Please refer to details on the link below:

https://www.r-bloggers.com/2013/01/converting-a-list-to-a-data-frame/

Basically, you get the tool by the code below,

require(devtools)

source_gist(4676064)

Then, use "as.data.frame" to convert list to dataframe. df<-as.data.frame(list)

Another way is to use the code below and then transpose it. This code could apply to list with different lengths. "data.frame(lapply(list, "length<-", max(lengths(list))))"

whatever
  • 1
  • 2
  • 1
    I don't get it why do you need devtools or source something from that git to convert a list to data.frame? – StupidWolf Apr 08 '21 at 15:52
  • You don't necessarily need it, but this is a simpler way for beginners to convert lists to data frames, with detailed documentation and examples. – whatever Apr 08 '21 at 22:31