Angenommen, ich habe eine by 2-Matrix und eine Funktion, die einen 2-Vektor als eines ihrer Argumente verwendet. Ich möchte die Funktion auf jede Zeile der Matrix anwenden und einen n-Vektor erhalten. Wie geht das in R?
Zum Beispiel möchte ich die Dichte einer 2D-Standardnormalverteilung auf drei Punkten berechnen:
bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out <- rbind(c(1, 2), c(3, 4), c(5, 6))
Wie wende ich die Funktion auf jede Zeile von an out
?
Wie übergebe ich Werte für die anderen Argumente neben den Punkten in der von Ihnen angegebenen Weise an die Funktion?
apply()
- es wird nach Zeilen gewobbelt (wenn das zweite Argument 1 ist, sonst nach Spalten), und die aktuelle Zeile (oder Spalte) ist immer das erste Argument. So werden Dinge definiert.MARGIN
Argument. Hier bedeutet dies, dass die Funktion auf die Zeilen angewendet wird (die erste Dimension indim(M)
). Wenn es 2 wäre, würde es die Funktion auf die Spalten anwenden.Wenn Sie allgemeine Funktionen wie Summe oder Mittelwert anwenden möchten, sollten Sie diese verwenden
rowSums
oderrowMeans
da sie schneller als derapply(data, 1, sum)
Ansatz sind. Ansonsten bleib beiapply(data, 1, fun)
. Sie können zusätzliche Argumente nach dem FUN-Argument übergeben (wie Dirk bereits vorgeschlagen hat):Dann können Sie so etwas tun:
quelle
Hier ist ein kurzes Beispiel für die Anwendung einer Funktion auf jede Zeile einer Matrix. (Hier normalisiert die angewendete Funktion jede Zeile auf 1.)
Hinweis: Das Ergebnis von
apply()
musste mit transponiert werdent()
, um das gleiche Layout wie die Eingabematrix zu erhaltenA
.Ergebnis:
quelle
Der erste Schritt wäre, das Funktionsobjekt zu erstellen und es dann anzuwenden. Wenn Sie ein Matrixobjekt mit der gleichen Anzahl von Zeilen möchten, können Sie es vordefinieren und das Objekt [] -Formular wie abgebildet verwenden (andernfalls wird der zurückgegebene Wert zu einem Vektor vereinfacht):
Wenn Sie andere als Ihre Standardparameter verwenden möchten, sollte der Aufruf benannte Argumente nach der Funktion enthalten:
apply () kann auch für höherdimensionale Arrays verwendet werden, und das MARGIN-Argument kann sowohl ein Vektor als auch eine einzelne Ganzzahl sein.
quelle
Bewerben macht den Job gut, ist aber ziemlich langsam. Die Verwendung von sapply und vapply könnte nützlich sein. dplyrs zeilenweise könnte auch nützlich sein. Sehen wir uns ein Beispiel an, wie ein zeilenweises Produkt eines Datenrahmens erstellt wird.
Beachten Sie, dass das Zuweisen zu Variablen vor der Verwendung von vapply / sapply / apply eine gute Vorgehensweise ist, da dies die Zeit erheblich verkürzt. Sehen wir uns die Ergebnisse der Mikrobenchmark an
Schauen Sie sich genau an, wie t () verwendet wird
quelle
b <- t(iris[1:10, 1:3])
und verwendet habenapply(b, 2 prod)
.Ein anderer Ansatz, wenn Sie einen variierenden Teil des Datasets anstelle eines einzelnen Werts verwenden möchten, ist die Verwendung
rollapply(data, width, FUN, ...)
. Durch die Verwendung eines Vektors mit Breiten können Sie eine Funktion auf ein variierendes Fenster des Datasets anwenden. Ich habe dies verwendet, um eine adaptive Filterroutine zu erstellen, obwohl sie nicht sehr effizient ist.quelle