Looking for r Keywords? Try Ask4Keywords

R LanguageKontrollieren Sie Flussstrukturen


Bemerkungen

Bei Schleifen handelt es sich um eine Flusssteuerungsmethode zum Wiederholen einer Aufgabe oder einer Gruppe von Aufgaben über eine Domäne. Die Kernstruktur einer for-Schleife ist

for ( [index] in [domain]){
  [body]
}

Woher

  1. [index] ist ein Name, der für jede Iteration der Schleife genau einen Wert von [domain] annimmt.
  2. [domain] ist ein Vektor von Werten, über den iteriert werden soll.
  3. [body] ist der Satz von Anweisungen, die bei jeder Iteration anzuwenden sind.

Betrachten Sie als triviales Beispiel die Verwendung einer for-Schleife, um die kumulative Summe eines Wertevektors zu erhalten.

x <- 1:4
cumulative_sum <- 0
for (i in x){
  cumulative_sum <- cumulative_sum + x[i]
}
cumulative_sum

Struktur von for-Schleifen optimieren

Für Schleifen kann es nützlich sein, Aufgaben zu konzeptionieren und auszuführen, die wiederholt werden sollen. Wenn sie nicht sorgfältig erstellt werden, können sie im Vergleich zu den bevorzugten Funktionen der apply sehr langsam ausgeführt werden. Nichtsdestotrotz gibt es eine Handvoll Elemente, die Sie in Ihre for-Schleife-Konstruktion integrieren können, um die Schleife zu optimieren. In vielen Fällen führt eine gute Konstruktion der for-Schleife zu einer Recheneffizienz, die der einer Anwendungsfunktion sehr nahe kommt.

Eine ordnungsgemäß erstellte for-Schleife baut auf der Kernstruktur auf und enthält eine Anweisung, die das Objekt deklariert, das jede Iteration der Schleife erfasst. Dieses Objekt sollte sowohl eine Klasse als auch eine Länge deklariert haben.

[output] <- [vector_of_length]
for ([index] in [length_safe_domain]){
  [output][index] <- [body]
}

Lassen Sie uns zur Veranschaulichung eine Schleife schreiben, um jeden Wert in einem numerischen Vektor zu x_squared <- x^2 (dies ist ein triviales Beispiel, das nur zur Veranschaulichung dient. Die "richtige" Art, diese Aufgabe zu x_squared <- x^2 wäre x_squared <- x^2 ).

x <- 1:100
x_squared <- vector("numeric", length = length(x))
for (i in seq_along(x)){
  x_squared[i] <- x[i]^2
}

x_squared wieder, dass wir zuerst einen Behälter für die Ausgabe x_squared haben und ihm die Klasse "numerisch" mit der gleichen Länge wie x . Außerdem haben wir mit der Funktion seq_along eine "length safe domain" seq_along . seq_along erzeugt einen seq_along für ein Objekt, das für for-Schleifen geeignet ist. Die Verwendung for (i in 1:length(x)) erscheint intuitiv. Wenn x die Länge 0 hat, versucht die Schleife, die Domäne von 1:0 zu durchlaufen, was zu einem Fehler führt (der 0. Index ist in R nicht definiert ).

Behälterobjekte und längensichere Domänen werden intern von der apply der Funktionen gehandhabt, und die Benutzer werden aufgefordert, den apply so weit wie möglich anstelle von for-Schleifen zu übernehmen. Bei richtiger Konstruktion kann eine for-Schleife jedoch gelegentlich eine größere Code-Klarheit bei minimalem Effizienzverlust bieten.

Vektorisieren für Loops

Schleifen können häufig ein nützliches Werkzeug sein, um die Aufgaben zu konzipieren, die in jeder Iteration ausgeführt werden müssen. Wenn die Schleife vollständig entwickelt und konzipiert ist, kann es vorteilhaft sein, aus der Schleife eine Funktion zu machen.

In diesem Beispiel werden wir eine for-Schleife entwickeln, um den Mittelwert jeder Spalte im mtcars Dataset zu berechnen (wiederum ein triviales Beispiel, wie es mit der Funktion colMeans ).

column_mean_loop <- vector("numeric", length(mtcars))
for (k in seq_along(mtcars)){
  column_mean_loop[k] <- mean(mtcars[[k]])
}

Die for-Schleife kann in eine Apply-Funktion umgewandelt werden, indem der Hauptteil der Schleife als Funktion umgeschrieben wird.

col_mean_fn <- function(x) mean(x)
column_mean_apply <- vapply(mtcars, col_mean_fn, numeric(1))

Und um die Ergebnisse zu vergleichen:

identical(column_mean_loop, 
          unname(column_mean_apply)) #* vapply added names to the elements
                                     #* remove them for comparison

Die Vorteile der vektorisierten Form sind, dass wir einige Codezeilen entfernen konnten. Die Mechanik der Bestimmung der Länge und des Typs des Ausgabeobjekts und des Iterierens über eine Länge sichere Domäne wird von der Apply-Funktion für uns behandelt. Außerdem ist die Apply-Funktion etwas schneller als die Schleife. Der Geschwindigkeitsunterschied ist in menschlicher Hinsicht oft vernachlässigbar, abhängig von der Anzahl der Iterationen und der Komplexität des Körpers.

Kontrollieren Sie Flussstrukturen Verwandte Beispiele