dc3
dc3

Reputation: 188

Transforming a list with differing number of elements to a data frame

I am trying to create a data frame by combining a data frame with a list. The problem is that each element of the list is not the same length. I read this link: http://www.r-bloggers.com/converting-a-list-to-a-data-frame/ and example four is exactly what I need, but I want to automate the process of naming the rows. I have over 100 rows I need to name and I don't want to name them all explicitly.

example <- list("a", c("b", "c"), c("d", "e", "f"))

should look like this:

row1 | a <NA> <NA>
row2 | b  c   <NA>
row3 | d  e    f

Upvotes: 0

Views: 1070

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269491

Convert each list component to a "ts" class object, cbind them to an "mts" class object (this will pad with NAs), and transpose giving a character matrix, mat. Set the row names. Finally convert that to a data frame. No packages are used.

mat <- t(do.call(cbind, Map(ts, example)))
rownames(mat) <- paste0("row", seq_along(example)) ##
DF <- as.data.frame(mat, stringsAsFactors = FALSE) ###

giving:

> DF
     V1   V2   V3
row1  a <NA> <NA>
row2  b    c <NA>
row3  d    e    f

Note: The question asked for a data frame and for row names; however, if row names are not needed omit the line marked ## and if a character matrix is sufficient then omit the line marked ###.

Update Fixed spelling of stringsAsFactors. Also minor simplification, add Note.

Upvotes: 1

akrun
akrun

Reputation: 887048

We can use stri_list2matrix to convert the list to matrix. It will fill NA for the list elements that have length less than the max length found in the list.

library(stringi)
stri_list2matrix(example, byrow=TRUE)
#    [,1] [,2] [,3]
#[1,] "a"  NA   NA  
#[2,] "b"  "c"  NA  
#[3,] "d"  "e"  "f" 

Or another option is from base R, where we assign the length to the maximum length, thereby filling NA for the list elements with less length. We use sapply so that when the list elements are of equal length, it simplify to matrix.

t(sapply(example, `length<-`, max(lengths(example))))
#   [,1] [,2] [,3]
#[1,] "a"  NA   NA  
#[2,] "b"  "c"  NA  
#[3,] "d"  "e"  "f" 

NOTE: No packages are used here ... If you need a data.frame, wrap the output with as.data.frame.

Upvotes: 1

Related Questions