2016-06-22 17 views
1

I a eine Funktion zu einem Matrix-Eingang angewandt werden soll, würde diese Funktion das erste Element c[a[1]] ändern und die nächsten Elemente b[a[i],a[i+1]] ab i = 1 bis zu i = ncol(a) - 1.mapply für eine bessere Leistung

Beispiel Eingabe:

a <- matrix(c(1,4,3,1),nrow=1) 
b <- matrix(1:25,ncol=5,nrow=5) 
c <- matrix(4:8,ncol=5,nrow=1) 

erwartete Ausgabe:

>a 
4 16 14 3 

#c[a[1]] gave us the first element: 4 
#b[a[1],a[2]] gave us the second element: 16 
#b[a[2],a[3]] gave us the third element: 14 
#b[a[3],a[4]] gave us the fourth element: 3 

Ich habe mapply() bisher ohne Erfolg zu nutzen versucht. Die Idee ist, Schlaufen zu vermeiden, da diese Dinge zu großer Leistungsabnahme in R führen können

Antwort

8

Schritt 1: einzigen Index unter Verwendung für die Matrix

In R Matrixelementen gespeichert ist, in Spaltenhauptordnung in eine Vektor Adressieren , so ist A[i, j] das gleiche wie A[(j-1)*nrow(A) + i]. Betrachten wir ein Beispiel von Zufalls 3-mal-3-Matrix:

set.seed(1); A <- round(matrix(runif(9), 3, 3), 2) 

> A 
    [,1] [,2] [,3] 
[1,] 0.27 0.91 0.94 
[2,] 0.37 0.20 0.66 
[3,] 0.57 0.90 0.63 

Nun Diese Matrix besteht aus 3 Reihen (nrow(A) = 3). Vergleichen:

A[2,3] # 0.66 
A[(3-1) * 3 + 2] # 0.66 

Schritt 2: Vektorisierung

Sie mehrere Elemente einer Matrix zu einer Zeit ansprechen kann. Sie können dies jedoch nur mit dem Einzelindexmodus (nicht zu genau hier, siehe @ alexis_laz's Bemerkung später). Zum Beispiel, wenn Sie A[1,2] und A[3,1], zu extrahieren, aber wenn Sie das tun:

A[c(1,3), c(2,1)] 
#  [,1] [,2] 
# [1,] 0.91 0.27 
# [2,] 0.90 0.57 

Sie erhalten tatsächlich einen Block. Nun, wenn Sie einzelne Indizierung verwenden, erhalten Sie, was Sie brauchen:

A[3 * (c(2,1) - 1) + c(1,3)] 
# [1] 0.91 0.57 

Schritt 3: getting einzigen Index für Ihr Problem

Angenommen n <- length(a) und Sie möchten die Elemente von b Adresse:

a[1] a[2] 
a[2] a[3] 
.  . 
.  . 
a[n-1] a[n] 

können Sie einzelnen Index nrow(b) * (a[2:n] - 1) + a[1:(n-1)] verwenden.

Schritt 4: Komplettlösung

Da Sie nur einzelne Zeile für a und c haben, können Sie sie als Vektoren anstatt Matrizen gespeichert werden sollte.

a <- c(1,4,3,1) 
c <- 4:8 

Wenn Sie eine Matrix gegeben wurden und haben keine andere Wahl (wie sie sind zur Zeit sind in Ihrer Frage), können Sie sie in Vektoren durch konvertieren:

a <- as.numeric(a) 
c <- as.numeric(c) 

Nun, wie diskutiert, haben wir Index für die Adresse b Matrix:

n <- length(a) 
b_ind <- nrow(b) * (a[2:n] - 1) + a[1:(n-1)] 

Sie auch a[1] Element c als erstes Element des Endergebnisses adressieren, also müssen wir concatena te: c[a[1]] und b[b_ind] von:

a <- c(c[a[1]], b[b_ind]) 
# > a 
# [1] 4 16 14 3 

Dieser Ansatz ist vollständig vektorisiert, sogar besser als *apply Familie.


alexis_laz Bemerkung

alexis_laz erinnert mich, dass wir "Matrix-Index" als auch, also verwenden können, können wir auch Matrix b über Adresse:

b[cbind(a[1:(n-1)],a[2:n])] ## or b[cbind(a[-n], a[-1])] 

Aber ich denke, die Verwendung einzelner Index ist etwas schneller, weil wir den Index Matrix für Zeile zugreifen müssen, um b zu adressieren, so zahlen wir höhere Speicher Latenz als mit Vektor-Index.

+0

danke für die schnelle antwort. Es scheint, dass b_ind = b [b_ind] ... Ich verstehe nicht die Logik hinter dieser Aussage b_ind <- nrow (b) * (a [-1] - 1) + a [1: (Länge (a) -1)] Ich werde durcharbeiten und sehen, ob Leistung besser ist als eine bloße Schleife und zurück zu dir morgen – Imlerith

+0

musste es noch einmal versuchen ... Ich verstand es jetzt (war nicht bewusst, R Matrix auf diese Weise zu organisieren zu dieser eigentümlichen Beziehung führen) wäre auch interessant gewesen, eine Implementierung der Lösung zu sehen, da ich nur wenig Verständnis dafür habe, wie sie in "komplexen" Problemen funktioniert – Imlerith

+0

Ich habe einige der Texte bearbeitet und entfernt, die nicht der Antwortteil sind (: -). Sie können jedoch ein Rollback durchführen, wenn Sie es für nötig halten. (Plus ein - im Wesentlichen haben Sie 8 Punkte gewonnen). Nimm auch nicht die Downvotes ernst ... – akrun

Verwandte Themen