¿Cómo hago una matriz a partir de una lista de vectores en R?

102

Objetivo: a partir de una lista de vectores de igual longitud, cree una matriz donde cada vector se convierta en una fila.

Ejemplo:

> 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

Quiero:

      [,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
fuente

Respuestas:

124

Una opción es usar 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
fuente
5
Entonces, la diferencia entre esto y el rbind () estándar es que do.call () pasa cada elemento de la lista como un argumento separado, ¿es así? do.call (rbind, a) es equivalente a rbind (a [[1]], a [[2]] ... a [[10]])?
Matt Parker
5
do.call () es genial para este propósito, me gustaría que estuviera mejor "documentado" en los materiales introductorios.
andrewj
16

simplify2arrayes una función básica bastante intuitiva. Sin embargo, dado que el valor predeterminado de R es completar primero los datos por columnas, deberá transponer la salida. ( sapplyusos simplify2array, como se documenta en 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
fuente
12

No es sencillo, pero funciona:

> 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
fuente
1
¡Con rjsonresultados, colMeansfunciona solo para este método! ¡Gracias!
mpyw
10

La matrixfunción incorporada tiene la buena opción de ingresar datos byrow. Combine eso con un unlisten su lista de fuentes le dará una matriz. También necesitamos especificar el número de filas para que pueda dividir los datos no listados. Es decir:

> 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
fuente
O llenar una matriz por columnas y luego transponer: t( matrix( unlist(a), ncol=length(a) ) ).
Kalin
8
t(sapply(a, '[', 1:max(sapply(a, length))))

donde 'a' es una lista. Funcionaría para un tamaño de fila desigual

Arihant
fuente
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
aprendiz
fuente
1
Esto simplemente no funcionará si las filas no tienen la misma longitud, mientras que do.call (rbind, ...) todavía funciona.
2013
¿Alguna pista de cómo hacer que funcione para un tamaño de fila desigual con NA para los datos de fila que faltan?
Arihant
1
@rwst En realidad, do.call (rbind, ...) no funciona para vectores de longitud desigual, a menos que realmente pretenda reutilizar el vector al completar la fila al final. Consulte la respuesta de Arihant para ver una forma que se completa con NAvalores al final.
Kalin