Wie erstelle ich eine Matrix aus einer Liste von Vektoren in R?


102

Ziel: Erstellen Sie aus einer Liste von Vektoren gleicher Länge eine Matrix, in der jeder Vektor zu einer Zeile wird.

Beispiel:

> 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

Ich will:

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

Antworten:


124

Eine Option ist zu verwenden 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

5
Der Unterschied zwischen diesem und dem Standard-rbind () besteht also darin, dass do.call () jedes Listenelement als separates Argument übergibt - stimmt das? do.call (rbind, a) entspricht rbind (a [[1]], a [[2]] ... a [[10]])?
Matt Parker

5
do.call () ist großartig für diesen Zweck, ich wünschte, es wäre besser in den Einführungsmaterialien "dokumentiert".
Andrewj

16

simplify2arrayist eine Basisfunktion, die ziemlich intuitiv ist. Da R standardmäßig Daten zuerst nach Spalten ausfüllt, müssen Sie die Ausgabe transponieren. ( sapplyverwendet simplify2array, wie in dokumentiert 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

12

Nicht einfach, aber es funktioniert:

> 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

1
Funktioniert mit rjsonErgebnissen colMeansnur für diese Methode! Danke dir!
mpyw

10

Die eingebaute matrixFunktion bietet die nette Möglichkeit, Daten einzugeben byrow. Kombinieren Sie dies mit einem unlistauf Ihrer Quellliste, um eine Matrix zu erhalten. Wir müssen auch die Anzahl der Zeilen angeben, damit die nicht aufgelisteten Daten aufgelöst werden können. Das ist:

> 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

Oder füllen Sie eine Matrix mit Spalten und transponieren Sie dann : t( matrix( unlist(a), ncol=length(a) ) ).
Kalin

8
t(sapply(a, '[', 1:max(sapply(a, length))))

Dabei ist 'a' eine Liste. Würde für ungleiche Zeilengröße funktionieren


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

1
Dies funktioniert einfach nicht, wenn die Zeilen nicht dieselbe Länge haben, während do.call (rbind, ...) weiterhin funktioniert.
Erstes

Gibt es Hinweise, wie es bei ungleicher Zeilengröße mit NA für die fehlenden Zeilendaten funktioniert?
Arihant

1
@rwst Tatsächlich funktioniert do.call (rbind, ...) nicht für Vektoren ungleicher Länge, es sei denn, Sie beabsichtigen wirklich, den Vektor beim Ausfüllen der Zeile am Ende wiederzuverwenden. In Arihants Antwort finden Sie eine Möglichkeit, NAdie stattdessen am Ende mit Werten gefüllt wird.
Kalin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.