2014-04-28 5 views
6

In meinem R Programm habe ich eine "for" -Schleife der folgenden Form:Wie vermeidet man hier eine Schleife in R?

for(i in 1:I) 
{ 
res[i] <- a[i:I] %*% b[i:I] 
} 

wo res, a und b Vektoren der Länge sind I.

Gibt es eine einfache Möglichkeit, diese Schleife zu vermeiden und res direkt berechnen? Wenn ja, wäre das effizienter?

Vielen Dank im Voraus!

+1

Warum verwenden Sie eine Matrixmultiplikation für 1d Vektoren? –

+3

Wahrscheinlich, weil ich Autodidakt und ahnungslos ... – Martin

Antwort

9

Dies ist die „umgekehrte cumsum“ von a*b

rev(cumsum(rev(a) * rev(b))) 
+0

Zeitfahren in Prozess ... :-) –

+0

@CarlWitthoft voran zu gehen, aber mit 'cumsum()' die Multiplikation geschieht nur einmal, so läuft es in _O (n) _. Die Schleife sollte in _O (n^2) _ laufen. – ilir

+2

Selbst '% *%' mit '*' in Justins ersetzt, die medianen Zeiten sind 360 und 87700 Mikrosekunden, also keine Überraschung 'cumsum' ist von viel schneller. –

2

Solange res bereits von der Länge I ist, ist die for-Schleife nicht "inkorrekt" und die Anwendungslösungen werden nicht wirklich schneller sein. Jedoch kann unter Verwendung bewerben prägnanter ... (wenn potenziell weniger lesbar)

Etwas wie folgt aus:

res <- sapply(seq_along(a), function(i) a[i:I] %*% b[i:I]) 

sollte als Einzeiler arbeiten.


an meinem ersten Satz erweitern. Während die in R verfügbare inhärente Vektorisierung sehr praktisch und oft der schnellste Weg ist, ist es nicht immer kritisch, for-Schleifen zu vermeiden. Darunter bestimmt die apply Familie die Größe der Ausgabe und weist sie vor dem "Looping" vor.

+0

nur klar zu sein - dies beschleunigt die Berechnung nicht über die von einer Schleife nach oben, nicht wahr? –

+0

Korrekt. Wenn der Code in der for-Schleife "res <- rbind (res, ...)" wäre, wäre die anwendbare Version viel schneller. – Justin

+1

Auch mit 'Summe (a [i: 1] * b [i: 1])' sollte geringfügig schneller als die Matrixmultiplikation sein. – ilir

Verwandte Themen