2016-04-11 7 views
3

Ich habe eine Frage über die Indizierung von 3 Dim-Arrays.R Indizierung von Arrays. Wie man ein 3-dimensionales Array unter Verwendung einer Matrix für die 3. Dimension indiziert

Say I

x<- c(1:36) 
dim(x) <- c(3,4,3) 

heute ein 3-dimensionales Array haben möchte ich aus dieser Arraywerte extrahieren, gemäß einer Matrix der 3. Dimension Indizes für alle [i,j] Positionen zu halten.

y <- c(rep(1,4),rep(2,4),rep(3,4)) 
dim(y) <- c(3,4) 

y 
     [,1] [,2] [,3] [,4] 
[1,] 1 1 2 3 
[2,] 1 2 2 3 
[3,] 1 2 3 3 

So sollte das Ergebnis dieser werden geben:

 [,1] [,2] [,3] [,4] 
[1,] 1 4 19 34 
[2,] 2 17 20 35 
[3,] 3 18 33 36 

Gibt es eine elegante Art und Weise, dies zu tun? Ich weiß, wie man zwei for-Schleifen benutzt, um über das Array zu gehen, aber das ist zu langsam für meine Daten.

Antwort

6

help("[") sagt uns dies:

Matrices und Arrays

[...]

Eine dritte Form der Indexierung erfolgt über eine numerische Matrix mit der eine Spalte für jede Dimension : Jede Zeile der Indexmatrix wählt dann ein einzelnes Element des Arrays aus, und das Ergebnis ist ein Vektor.

So verwandeln wir Ihre y Matrix in eine Form, die damit übereinstimmt.

library(reshape2) 
z <- x[as.matrix(melt(y))] 
dim(z) <- dim(y) 
#  [,1] [,2] [,3] [,4] 
#[1,] 1 4 19 34 
#[2,] 2 17 20 35 
#[3,] 3 18 33 36 
+0

Vielen Dank für die Hilfe. Und ja, das Lesen von Hilfedateien ist eine sehr gute Idee. Immer. Übrigens ist es möglich, einige Bedingungstests in der Matrix der Indizes zu verwenden? wie x> 3? – Atomhamster

4

Ich betrachte dies als eine Gelegenheit für einige Code Golf. Es ist auf jeden Fall möglich, dies als ein Liner zu tun:

> `dim<-`(x[cbind(c(row(y)), c(col(y)), c(y))], dim(y)) 
    [,1] [,2] [,3] [,4] 
[1,] 1 4 19 34 
[2,] 2 17 20 35 
[3,] 3 18 33 36 

Wie @ Roland Antwort zeigt, Matrix/array Indexierungs beinhaltet eine n -Säule Matrix Erstellen und Einstellen der Spalten Reihe gleich sind, Spalte usw. Position jeder Dimension eines n -dimensionalen Arrays. Wir können die row()col() und Funktionen verwenden, die Zeilen- und Spaltenpositionen jedes Elements in y zu extrahieren:

> row(y) 
    [,1] [,2] [,3] [,4] 
[1,] 1 1 1 1 
[2,] 2 2 2 2 
[3,] 3 3 3 3 
> col(y) 
    [,1] [,2] [,3] [,4] 
[1,] 1 2 3 4 
[2,] 1 2 3 4 
[3,] 1 2 3 4 

und y selbst gibt die dritte Dimension-Positionen. Umhüllen jeder dieser in c() verwandelt sie in einen Vektor, so dass sie gemeinsam erstellt werden können, um eine Extraktionsmatrix zu erstellen.

Dann gibt es nur ein bisschen Spaß mit dim<-(), um alles auf einer Linie zu passen.

+0

Danke Thomas. Ich mag deinen Ehrgeiz. Ich bin auch ein großer Fan von nur Basisfunktionen, wenn möglich. Aber ich muss sagen, ich verstehe deinen Spaß nicht mit Dim. Wie funktioniert das? Was machen die Backticks? – Atomhamster

+0

@Atomhamster Wenn du 'dim (x) <- dim (y)' machst, machst du eigentlich 'dim <- (x, dim (y))' wobei '" dim <- "' der Name von a ist Funktion. Dies ist nützlich, wenn Sie eine Funktion wie 'dim <-()' oder 'name <-()', usw. verwenden möchten.ohne zuerst das linke Objekt zu erstellen. (Die Backticks lassen Sie einfach die '' dim <-() "Funktion direkt aufrufen, aber sie sind schwer zu schreiben in diesem Kommentar Markup.) – Thomas

+0

Vielen Dank @Thomas für die Erklärung. Sehr interessant, diesen Trick zu kennen. Ich denke, es könnte mir eine beträchtliche Anzahl von Zeilen in meinen Funktionen ersparen. – Atomhamster

Verwandte Themen