Zuhaib Ahmed
Zuhaib Ahmed

Reputation: 507

Converting a list of lists into a data frame

I have a function that first generates a list of vectors (generated by using lapply), and then cbinds it to a column vector. I thought this would produce a dataframe. However, it produces a list of lists.

The cbind function isn't working as I thought it would.

Here's a small example of what the function is generating

col_test <- c(1, 2, 1, 1, 2)
lst_test <- list(c(1, 2 , 3), c(2, 2, 2), c(1, 1, 2), c(1, 2, 2), c(1, 1, 1))
a_df <- cbind(col_test, lst_test)

Typing

> a_df[1,]

gives the output

$`col_test`
[1] 1

$lst_test
[1] 1 2 3

I'd like the data frame to be

     [,1] [,2] [,3] [,4]
[1,] 1    1    2    3

[2,] 2    2    2    2

[3,] 1    1    1    2

[4,] 1    1    2    2

[5,] 2    1    1    1

How do I get it into this form?

Upvotes: 3

Views: 257

Answers (4)

Rickard
Rickard

Reputation: 3690

col_test <- c(1, 2, 1, 1, 2)
lst_test <- list(c(1, 2 , 3), c(2, 2, 2), c(1, 1, 2), c(1, 2, 2), c(1, 1, 1))

name the sublists so we can use bind_rows

names(lst_test) <- 1:length(lst_test)   
lst_test1 <- bind_rows(lst_test)

the bind_rows function binds by cols in this case so we need to pivot it

lst_test_pivot <- t(lst_test1) 

but this gives us a matrix, so we need to cast it back to a dataframe

lst_test_pivot_df <- as.data.frame(lst_test_pivot)

now it works as

cbind(col_test, lst_test_pivot_df)

now produces

  col_test V1 V2 V3
1        1  1  2  3
2        2  2  2  2
3        1  1  1  2
4        1  1  2  2
5        2  1  1  1

Upvotes: 1

d.b
d.b

Reputation: 32558

do.call(rbind, Map(c, col_test, lst_test))
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    2    3
#[2,]    2    2    2    2
#[3,]    1    1    1    2
#[4,]    1    1    2    2
#[5,]    2    1    1    1

Upvotes: 1

xenopus
xenopus

Reputation: 78

data.frame(col_test,t(as.data.frame(lst_test)))

Upvotes: 1

jdobres
jdobres

Reputation: 11957

This should do the trick. Note that we are using do.call so that the individual elements of lst_test are sent as parameters to cbind, which prevents cbind from creating a list-of-lists. t is used to transpose the resulting matrix to your preferred orientation, and finally, one more cbind with col_test inserts that data as well.

library(tidyverse)

mat.new <- do.call(cbind, lst_test) %>% 
  t %>% 
  cbind(col_test, .) %>% 
  unname

     [,1] [,2] [,3] [,4]
[1,]    1    1    2    3
[2,]    2    2    2    2
[3,]    1    1    1    2
[4,]    1    1    2    2
[5,]    2    1    1    1

Upvotes: 0

Related Questions