For-Schleife in R mit Beispielen für Liste und Matrix

⚡ Intelligente Zusammenfassung

Die For-Schleife in R führt einen Codeblock einmal für jedes Element einer Sequenz aus, unabhängig davon, ob es sich bei dieser Sequenz um einen Vektor, eine Liste oder eine Matrix handelt. Diese Anleitung iteriert über alle diese Typen und zeigt, wann vektorisierter Code die bessere Wahl ist.

  • 🔁 Kernsyntax: for (i in vector) { expression } weist i nacheinander jedes Element zu und führt den Rumpf aus.
  • 📋 Beliebiges Objekt: Mit der gleichen Syntax kann man einen Vektor, eine Liste, eine Spalte eines Dataframes oder die Zeilen einer Matrix durchlaufen.
  • 🧮 Verschachtelte Schleifen: Eine Matrix benötigt zwei Schleifen, eine äußere für die Zeilen und eine innere für die Spalten.
  • 🛑 Ablaufsteuerung: break verlässt die Schleife vollständig, next überspringt nur das aktuelle Element.
  • Vektorisierung zuerst: Die integrierten vektorisierten Operationen und die apply-Familie sind schneller und kürzer als eine explizite Schleife.
  • ⚠️ Sichere Abläufe: Verwenden Sie seq_along(x) anstelle von 1:length(x), da diese Funktion fehlerhaft funktioniert, wenn das Objekt leer ist.

For-Schleife in R Listenmatrix

A for-Schleife Wiederholt einen Codeblock einmal für jedes Element einer Sequenz. Diese Sequenz kann ein Vektor, eine Liste, ein Dataframe, eine Matrix oder ein beliebiges anderes Objekt sein, über das R iterieren kann. R unterscheidet zwischen Groß- und Kleinschreibung, daher wird das Schlüsselwort immer kleingeschrieben. für Die geschweiften Klammern sind immer dann erforderlich, wenn der Textkörper sich über mehr als eine Zeile erstreckt.

Syntax der For-Schleife in R

for (i in vector) {
    Exp
}

Dabei steht:

R durchläuft alle Variablen im Vektor und führt die in exp geschriebene Berechnung durch.

For-Schleife in R
For-Schleife in R

Schauen wir uns ein paar Beispiele an.

For-Schleife in R Beispiel 1: Wir durchlaufen alle Elemente eines Vektors und geben den aktuellen Wert aus.

# Create fruit vector
fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana')
# Create the for statement
for ( i in fruit){ 
 print(i)
}

Ausgang:

## [1] "Apple"
## [1] "Orange"
## [1] "Passion fruit"
## [1] "Banana"

For-Schleife in R Beispiel 2Quadriere jede ganze Zahl von 1 bis 4 und speichere die Ergebnisse in einer Liste.

# Create an empty list
list <- c()
# Create a for statement to populate the list
for (i in seq(1, 4, by=1)) {
  list[[i]] <- i*i
}
print(list)

Ausgang:

## [1]   1  4 9 16

For-Schleifen sind im maschinellen Lernen nützlich. Die Optimierung eines Regularisierungsparameters bedeutet, viele Kandidatenwerte zu testen und beizubehalten.ping Diejenige, die die Verlustfunktion minimiert, und eine for-Schleife ist der einfachste Weg, diesen Bereich zu durchlaufen.

Wie man break und next in einer For-Schleife verwendet

Zwei Schlüsselwörter unterbrechen den normalen Ablauf einer for-Schleife.

  • brechen Verlässt die Schleife sofort und überspringt alle verbleibenden Elemente.
  • weiter gibt das aktuelle Element auf und fährt mit dem nächsten fort.
fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana')

# break: stop at the first match
for (i in fruit) {
    if (i == 'Passion fruit') {
        print('Found it, stopping here')
        break
    }
    print(i)
}

# next: skip one element and carry on
for (i in fruit) {
    if (i == 'Orange') next
    print(i)
}

In verschachtelten Schleifen wirken `break` und `next` nur auf die innerste Schleife, die sie enthält. Um im Matrixbeispiel beide Schleifen beizubehalten, kann man eine Flag-Variable setzen und diese auch in der äußeren Schleife prüfen.

Verwenden Sie seq_along() für Indizes. Die Schleife `for (i in 1:length(x))` sieht harmlos aus, schlägt aber bei einem leeren Objekt fehl, da `1:0` die Sequenz 1, 0 erzeugt und die Schleife zweimal durchlaufen wird. `seq_along(x)` gibt stattdessen eine leere Sequenz zurück, sodass die Schleife korrekterweise übersprungen wird.

for (i in seq_along(fruit)) {
    cat(i, fruit[i], '\n')
}

Schleife über eine Liste

Kloping über eine Liste funktioniert genau wie looping über einen Vektor, mit der Ausnahme, dass jedes Element einen anderen Typ haben kann:

# Create a list with three vectors
fruit <- list(Basket = c('Apple', 'Orange', 'Passion fruit', 'Banana'), 
Money = c(10, 12, 15), purchase = FALSE)
for (p  in fruit) 
{ 
	print(p)
}

Ausgang:

## [1] "Apple" "Orange" "Passion fruit" "Banana"       
## [1] 10 12 15
## [1] FALSE

Schleife über eine Matrix

Eine Matrix hat zwei Dimensionen, Zeilen und Spalten. Um also jede Zelle zu durchlaufen, benötigt man zwei verschachtelte for-Schleifen: eine äußere für die Zeilen und eine innere für die Spalten.

# Create a matrix
mat <- matrix(data = seq(10, 20, by=1), nrow = 6, ncol =2)
# Create the loop with r and c to iterate over the matrix
for (r in 1:nrow(mat))   
    for (c in 1:ncol(mat))  
         print(paste("Row", r, "and column",c, "have values of", mat[r,c]))  

Ausgang:

## [1] "Row 1 and column 1 have values of 10"
## [1] "Row 1 and column 2 have values of 16"
## [1] "Row 2 and column 1 have values of 11"
## [1] "Row 2 and column 2 have values of 17"
## [1] "Row 3 and column 1 have values of 12"
## [1] "Row 3 and column 2 have values of 18"
## [1] "Row 4 and column 1 have values of 13"
## [1] "Row 4 and column 2 have values of 19"
## [1] "Row 5 and column 1 have values of 14"
## [1] "Row 5 and column 2 have values of 20"
## [1] "Row 6 and column 1 have values of 15"
## [1] "Row 6 and column 2 have values of 10" 

For-Schleife über einen Dataframe in R

Ein Dataframe ist eine Liste von Spalten, daher durchläuft eine einfache for-Schleife die Spalten anstatt der Zeilen. Das ist in der Regel das, was man möchte:

df <- data.frame(a = 1:5, b = 6:10, c = 11:15)

# Loop over the columns
for (col in names(df)) {
    cat(col, 'has mean', mean(df[[col]]), '\n')
}

Beachten Sie die doppelte Klammer. df[[col]] extracts gibt die Spalte als Vektor zurück, wohingegen df[col] einen einspaltigen Datenrahmen zurückgibt, den mean() nicht verarbeiten kann.

Kloping über Zeilen. Zeilenweises Durchlaufen ist zwar möglich, aber langsam, da R die Zeile bei jedem Durchlauf kopiert:

for (r in seq_len(nrow(df))) {
    cat('Row', r, 'sums to', sum(df[r, ]), '\n')
}

Bei Datenmengen über einige tausend Zeilen hinaus empfiehlt sich rowSums(df), apply(df, 1, sum) oder ein dplyr-Objekt. group_by() und summarise() Die Pipeline, die alle die gleiche Arbeit ohne das Kopieren erledigt.

For-Schleifen vs. Vektorisierung in R

R ist eine vektorisierte Sprache: Die meisten ihrer Operatoren und Funktionen wirken bereits im kompilierten C-Code auf ganze Vektoren gleichzeitig. Eine explizite Schleife, die eine vektorisierte Operation elementweise wiederholt, ist sowohl länger als auch langsamer.

# Loop version
squares <- c()
for (i in 1:4) {
    squares[i] <- i * i
}

# Vectorized version, same result
squares <- (1:4)^2
Aufgabe Loop Vektorisiertes Äquivalent
Elementweise Arithmetik für jedes Element x * 2, x + y, x^2
Wende eine Funktion pro Spalte an für über Namen(df) sapply(df, mean)
Wende eine Funktion pro Zeile an for over seq_len(nrow(df)) apply(df, 1, sum)
Erstelle eine Ergebnisliste for with list[[i]] <- … lapply(v, f)
Bedingte Umkodierung für mit wenn und sonst ifelse(cond, a, b)

Wenn eine Schleife immer noch die richtige Lösung ist. Verwenden Sie die for-Schleife, wenn jede Iteration vom vorherigen Ergebnis abhängt, wenn Sie einen externen Dienst aufrufen oder Dateien schreiben oder wenn bei einem kleinen Objekt die Übersichtlichkeit wichtiger ist als die Geschwindigkeit.

Wenn Sie eine Schleife benötigen, reservieren Sie den Speicherplatz vorab. Das Vergrößern eines Objekts innerhalb einer Schleife zwingt R dazu, es bei jedem Durchlauf zu kopieren. Erstellen Sie es daher zuerst in voller Größe:

# Slow: the vector is reallocated on every pass
out <- c()
for (i in 1:1000) out[i] <- i^2

# Fast: allocated once
out <- numeric(1000)
for (i in 1:1000) out[i] <- i^2

For-Schleife in R: Kurzübersicht

Alle in diesem Tutorial verwendeten Konstrukte sind unten aufgeführt:

Ziel Code
Schleife über einen Vektor
for (i in v) { print(i) }
Indizes sicher durchlaufen
for (i in seq_along(v)) { print(v[i]) }
Schleife über eine Liste
for (p in my_list) { print(p) }
Schleife über die Spalten des Datenrahmens
for (col in names(df)) { print(mean(df[[col]])) }
Schleife über eine Matrix
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c])
Die Schleife frühzeitig verlassen
if (condition) break
Überspringen Sie eine Iteration
if (condition) next
Ausgabe vorab reservieren
out <- numeric(n)

Häufig gestellte Fragen

Wenn x leer ist, gibt 1:length(x) die Sequenz 1, 0 zurück, und die Schleife wird zweimal für nicht vorhandene Elemente durchlaufen. seq_along(x) gibt eine leere Sequenz zurück, daher wird die Schleife korrekt übersprungen.

Die Schleife selbst ist nicht das Problem. Problematisch ist das Erzeugen eines Objekts innerhalb der Schleife, da R das gesamte Objekt bei jedem Durchlauf kopiert. Durch Vorab-Speicherung des Ergebnisses oder Verwendung einer vektorisierten Funktion lässt sich das Problem weitgehend beheben.

Spalten. Ein Dataframe ist eine Liste von Spalten, daher liefert jede Iteration eine ganze Spalte. Verwenden Sie `seq_len(nrow(df))` explizit, wenn Sie die Zeilen durchlaufen möchten.

For-Schleifen steuern Hyperparameter-Sweeps, Kreuzvalidierungs-Folds und Trainings-Epochen. Jede dieser Operationen hat eine bekannte Iterationsanzahl, wofür die For-Schleife genau konzipiert ist.

Ja. KI-Assistenten können die meisten elementweisen Schleifen in vektorisierte oder apply-familienäquivalente Ausdrücke umwandeln. Vergleichen Sie die Ausgabe beider Versionen mit `identical()`, bevor Sie die ursprüngliche Ausgabe ersetzen.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: