ke.re
ke.re

Reputation: 63

convert lists with differing lengths to data frame or data table in R

I have a list of lists. These lists differ in length.

listXYZ <- list(c("x1", "x2", "x3"),
                c("y1", "y2", "y3", "y4", "y5", "y6"),
                c("z1"))

I would like to convert the lists to a table for printing in knitr with xtable, but I want to avoid using plyr as I already have dplyr loaded and don't want confusion from commands available in both (nor to write package:: in front of everything). Without that constraint, I would use

 plyr::ldply(listXYZ, rbind)

but the simplest non-plyr equivalent I have seen is

  do.call(rbind, listXYZ)

and this replaces blank spaces by repeating the shorter lists until it reaches the length of the longest list. The blanks in the shorter lists should be filled with NA,

Other methods resulted in error messages because of the differing list lengths, such as:

 In (function (..., deparse.level = 1)  :
 number of columns of result is not a multiple of vector length (arg 1)

Is there a way to do this that scales up well (for larger lists)? In my case, the list will always have 5 rows, but the length of lists varies greatly.

Upvotes: 2

Views: 92

Answers (2)

s_baldur
s_baldur

Reputation: 33488

The issue you encounter can be dealt with by updating the length attribute.

len <- max(lengths(listXYZ))
t(sapply(listXYZ, `length<-`, len))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] "x1" "x2" "x3" NA   NA   NA  
[2,] "y1" "y2" "y3" "y4" "y5" "y6"
[3,] "z1" NA   NA   NA   NA   NA 

From documentation: when a vector is lengthened, it is padded out to its new length with NAs.

Upvotes: 1

James
James

Reputation: 66844

Indexing past the end of the vector results in NA, therefore you can use that to pad with NAs:

max_len <- max(sapply(listXYZ,length))
do.call("rbind",lapply(listXYZ,function(x) x[seq(max_len)]))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] "x1" "x2" "x3" NA   NA   NA  
[2,] "y1" "y2" "y3" "y4" "y5" "y6"
[3,] "z1" NA   NA   NA   NA   NA 

Upvotes: 0

Related Questions