2013-03-05 12 views
22

Wenn ich mehrere Matrizen habe, die ich erstellt habe, wie kann ich sie in einem Array kombinieren? Ich habe 8 Matrizen, die jeweils 200 Zeilen und 200 Spalten haben, und ich muss sie zu einem Array mit dim = 200,200,8 kombinieren. Ich möchte also, dass jede meiner Matrizen ein Stück meines Arrays ist.Kombinieren von Matrizen zu einem Array in R

+0

Does das Ergebnis muss ein 'Array' sein? Würde 'liste (x, y)' für dich arbeiten? – thelatemail

Antwort

14

Hier ist das Beispiel für zwei. Sie können dies leicht zu acht

# create two matricies with however many rows and columns 
x <- matrix(1:9 , 3 , 3) 
y <- matrix(10:18 , 3 , 3) 
# look at your starting data 
x 
y 

# store both inside an array, with the same first two dimensions, 
# but now with a third dimension equal to the number of matricies 
# that you are combining 
z <- array(c(x , y) , dim = c(3 , 3 , 2)) 

# result 
z 
0

verlängern Wie wäre es damit:

combmat <- array(dim=c(200,200,8), data=cbind(matrix1,matrix2,...,matrix8)) 
21

Sie die abind Funktion aus dem abind Paket verwenden können:

library(abind) 
newarray <- abind(mat1, mat2, mat3, mat4, along=3) 

## or if mats are in a list (a good idea) 

newarray <- abind(matlist, along=3) 
+3

Definitiv der richtige Weg, da 'abind' vom Benutzer viel mühsame und fehleranfällige Indexbuchhaltung übernimmt. –

2

Es hängt davon ab, ob Sie wollen kombinieren Sie sie Spalte-Haupt- oder Reihe-Haupt. Dies ist analog zur Verwendung von cbind und rbind zum Kombinieren von Vektoren in die Matrix. Da R speichert Matrizen in Spalte-Großauftrag ist dies die am einfachsten zu erreichen:

matrices <- list(
    matrix(1:9 , 3 , 3), 
    matrix(10:18 , 3 , 3) 
); 

#it is assumed all matrices in the list have equal dimensions 
array1 <- array(
    data = do.call(cbind, matrices), 
    dim = c(dim(matrices[[1]]), length(matrices)) 
); 

Die neue Dimension (2 in diesem Fall) wird die dritte Dimension werden. Geht man von dem Ausgang des Druckverfahrens, das sieht genau, weil sie den Druck durch die letzte Dimension teilt:

> print(array1) 
, , 1 

    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 

, , 2 

    [,1] [,2] [,3] 
[1,] 10 13 16 
[2,] 11 14 17 
[3,] 12 15 18 

Aber manchmal könnte man sich durch die erste Dimension statt kombinieren muß, zB:

array2 <- array (
    data = do.call(rbind, lapply(matrices, as.vector)), 
    dim = c(length(matrices), dim(matrices[[1]])) 
); 

print(array2[1,,]) 

    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 

Zum Beispiel sagen Sie, dass Sie diese Matrizen einem Datenrahmen mit Spalte zuweisen möchten; eine Matrix für jede Zeile. Dann werden die ersten Dimensionen, a.k.a nrow haben in dem Array und Datenrahmen entsprechen:

mydf <- data.frame(foo = 1:2, row.names=c("first", "second")) 
mydf$bar <- array1 
    Error in `$<-.data.frame`(`*tmp*`, "bar", value = 1:18) : 
    replacement has 3 rows, data has 2 

mydf$bar <- array2 
mydf$bar 
6

Hier ist eine Version ähnlich wie abind -ing, aber ohne zusätzliche Pakete zu verwenden. Sammeln Sie alles in ein list und dann sapply ‚s Option simplify= zu einem "array" nach Nichtstun zu jedem Teil der Liste verwenden (identity nur das Objekt zurückgibt und entsprechen function(x) x):

sapply(list(x,y), identity, simplify="array") 
# similarly to save a couple of keystrokes, the following is usually identical 
sapply(list(x,y), I, simplify="array") 

#, , 1 
# 
#  [,1] [,2] [,3] 
#[1,] 1 4 7 
#[2,] 2 5 8 
#[3,] 3 6 9 
# 
#, , 2 
# 
#  [,1] [,2] [,3] 
#[1,] 10 13 16 
#[2,] 11 14 17 
#[3,] 12 15 18 

Wenn Sie möchten, die Namen der einzelnen ursprünglichen Matrix in Ihrem neuen Array als Bezeichner zu erhalten, versuchen:

sapply(mget(c("x","y")), identity, simplify="array") 
+0

Die Funktion aperm kann weiter verwendet werden, um die Reihenfolge der Array-Dimensionen für 3-D-Array zu ändern: new.mat <- aperm (old.mat, c (3, 1, 2)). Auf diese Weise entspricht new.mat [1 ,,] den Matrizen [[1]]. –

0

Verwandte: How to stack multiple matrices in R

Das Problem mit allen Lösungen ist bisher, dass, wenn Matrizen (nicht data.frame s - für diese dplyr und data.table funktionieren gut) nicht die gleiche Reihenfolge der Zeilen und Spalten haben, binden wird Stapel Werte übereinander, die nicht in Beziehung stehen.

Wenn Sie die Namen in jeder Dimension überprüfen und berücksichtigen wollen, müssen Sie einen Blick auf narray:

enter image description here

(Haftungsausschluss: Ich das Paket geschrieben)

0
library('abind') 
abind(m1, m2, m3, along = 2.5) 
abind(m1, m2, m3, along = 3) 

m4 <- list(m1, m2, m3) 
abind(m4, along = 3) 

     along  input = matrix + matrix      output 
---------------------------------------------------------------------------- 
     0   split columns and row bind them     array 
     0.5  same as 0          array 
     1   combine matrices into one matrix by rowwise  matrix 
     1.5  split columns and column bind them    array 
     2   combine matrices into one matrix by columnwise matrix 
     2.5  Form an array with matrices      array 
     3   Same as 2.5          array 
Verwandte Themen