Reputation: 63
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
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
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