116

Goal: from a list of vectors of equal length, create a matrix where each vector becomes a row.

Example:

> a <- list()
> for (i in 1:10) a[[i]] <- c(i,1:5)
> a
[[1]]
[1] 1 1 2 3 4 5

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

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

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

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

[[6]]
[1] 6 1 2 3 4 5

[[7]]
[1] 7 1 2 3 4 5

[[8]]
[1] 8 1 2 3 4 5

[[9]]
[1] 9 1 2 3 4 5

[[10]]
[1] 10  1  2  3  4  5

I want:

      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5 
Christopher DuBois
  • 42,350
  • 23
  • 71
  • 93

6 Answers6

139

One option is to use do.call():

 > do.call(rbind, a)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5
Christopher DuBois
  • 42,350
  • 23
  • 71
  • 93
  • 5
    So the difference between this and the standard rbind() is that do.call() passes each list item as a separate arg - is that right? do.call(rbind,a) is equivalent to rbind(a[[1]], a[[2]]... a[[10]])? – Matt Parker Aug 25 '09 at 18:57
  • 5
    do.call() is great for this purpose, I wish it were better "documented" in the introductory materials. – andrewj Aug 28 '09 at 14:23
20

simplify2array is a base function that is fairly intuitive. However, since R's default is to fill in data by columns first, you will need to transpose the output. (sapply uses simplify2array, as documented in help(sapply).)

> t(simplify2array(a))
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5
Kalin
  • 1,691
  • 2
  • 16
  • 22
16

The built-in matrix function has the nice option to enter data byrow. Combine that with an unlist on your source list will give you a matrix. We also need to specify the number of rows so it can break up the unlisted data. That is:

> matrix(unlist(a), byrow=TRUE, nrow=length(a) )
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5
Kalin
  • 1,691
  • 2
  • 16
  • 22
  • Or fill a matrix by columns and then transpose: `t( matrix( unlist(a), ncol=length(a) ) )`. – Kalin Dec 22 '14 at 20:22
12

Not straightforward, but it works:

> t(sapply(a, unlist))
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5
Paolo
  • 2,795
  • 1
  • 20
  • 23
8
t(sapply(a, '[', 1:max(sapply(a, length))))

where 'a' is a list. Would work for unequal row size

Arihant
  • 589
  • 9
  • 24
3
> library(plyr)
> as.matrix(ldply(a))
      V1 V2 V3 V4 V5 V6
 [1,]  1  1  2  3  4  5
 [2,]  2  1  2  3  4  5
 [3,]  3  1  2  3  4  5
 [4,]  4  1  2  3  4  5
 [5,]  5  1  2  3  4  5
 [6,]  6  1  2  3  4  5
 [7,]  7  1  2  3  4  5
 [8,]  8  1  2  3  4  5
 [9,]  9  1  2  3  4  5
[10,] 10  1  2  3  4  5
learnr
  • 6,479
  • 4
  • 27
  • 23
  • 1
    This will simply not work if the rows don't have the same length, while do.call(rbind,...) still works. – rwst Dec 23 '13 at 09:42
  • any clues how to make it work for unequal row size with NA for the missing row data? – Arihant Jan 26 '14 at 15:42
  • 1
    @rwst Actually, do.call(rbind,...) does not work for unequal-length vectors, unless you really intend to have the vector reused when filling in the row at the end. See Arihant's response for a way that fills in with `NA` values at the end instead. – Kalin Dec 22 '14 at 20:42