For Loop in R med eksempler på List og Matrix

⚡ Smart opsummering

For Loop i R kører en kodeblok én gang for hvert element i en sekvens, uanset om sekvensen er en vektor, en liste eller en matrix. Denne gennemgang itererer over hver af dem og viser, hvornår vektoriseret kode er det bedste valg.

  • 🔁 Kernesyntaks: for (i in vector) { expression } tildeler hvert element til i efter tur og kører kroppen.
  • ???? Ethvert objekt: Den samme syntaks gennemgår en vektor, en liste, et datarammekolonnesæt eller rækkerne i en matrix.
  • 🧮 Indlejrede løkker: En matrix skal bruge to løkker, en ydre til rækker og en indre til kolonner.
  • 🛑 Flow kontrol: break forlader løkken helt og springer derefter kun det aktuelle element over.
  • ⚡ Vektorisering først: Indbyggede vektoriserede operationer og Apply-familien er hurtigere og kortere end et eksplicit loop.
  • ⚠️ Sikre sekvenser: Brug seq_along(x) i stedet for 1:length(x), som ikke fungerer korrekt, når objektet er tomt.

For Loop i R-listematrix

A til løkke gentager en kodeblok én gang for hvert element i en sekvens. Denne sekvens kan være en vektor, en liste, en dataramme, en matrix eller ethvert andet objekt, som R kan iterere over. R skelner mellem store og små bogstaver, så nøgleordet er altid med små bogstaver forum, og krøllede bøjler er påkrævet, når kroppen strækker sig over mere end én linje.

For Loop-syntaks i R

for (i in vector) {
    Exp
}

Her,

R vil sløjfe over alle variablerne i vektor og udføre beregningen skrevet inde i exp.

Til Loop in R
Til Loop in R

Lad os se et par eksempler.

For Loop in R Eksempel 1: Vi itererer over alle elementerne i en vektor og udskriver den aktuelle værdi.

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

Output:

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

For Loop in R Eksempel 2: kvadrer hvert heltal fra 1 til 4 og gemmer resultaterne i en 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)

Output:

## [1]   1  4 9 16

For-løkker er nyttige i maskinlæringsarbejde. At justere en regulariseringsparameter betyder at teste mange kandidatværdier og holde demping den der minimerer tabsfunktionen, og en for-løkke er den enkle måde at gennemsøge dette område.

Sådan bruger du break og next i en For-løkke

To nøgleord afbryder den normale rækkefølge af en for-løkke.

  • bryde afslutter løkken med det samme og springer alle resterende elementer over.
  • næste forlader kun det nuværende element og går videre til det følgende.
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)
}

I indbyggede løkker, afbryd og reager derefter kun på den inderste løkke, der indeholder dem. For at lade begge løkker være i matrixeksemplet, sæt en flagvariabel og test den også i den ydre løkke.

Brug seq_along() til indekser. At skrive for (i i 1:length(x)) ser harmløst ud, men fejler på et tomt objekt, fordi 1:0 producerer sekvensen 1, 0, og løkken kører to gange. seq_along(x) returnerer i stedet en tom sekvens, så løkken springes korrekt over:

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

For løkke over en liste

Looping over en liste fungerer præcis som toiletping over en vektor, bortset fra at hvert element kan indeholde en forskellig type:

# 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)
}

Output:

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

For løkke over en matrix

En matrix har to dimensioner, rækker og kolonner, så iteration over hver celle kræver to indbyggede for-løkker: en ydre til rækkerne og en indre til kolonnerne.

# 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]))  

Output:

## [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 Loop Over en Data Frame i R

En dataramme er en liste af kolonner, så en almindelig for-løkke gennemgår sine kolonner i stedet for sine rækker. Det er normalt det, du ønsker:

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')
}

Bemærk den dobbelte parentes. df[[col]] extracbruger kolonnen som en vektor, hvorimod df[col] returnerer en dataframe med én kolonne, som mean() ikke kan håndtere.

Looping over rækker. Rækkevis iteration er mulig, men langsom, fordi R kopierer rækken ved hver gennemgang:

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

For alt ud over et par tusinde rækker, foretrækkes rowSums(df), apply(df, 1, sum) eller en dplyr group_by() og summary() pipeline, som alle udfører det samme arbejde uden kopiering.

For Loops vs. Vektorisering i R

R er et vektoriseret sprog: de fleste af dets operatorer og funktioner virker allerede på hele vektorer på én gang i kompileret C-kode. En eksplicit løkke, der gentager en vektoriseret operation element for element, er både længere og langsommere.

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

# Vectorized version, same result
squares <- (1:4)^2
Opgaver Loop Vektoriseret ækvivalent
Elementvis aritmetik for over hvert element x * 2, x + y, x^2
Anvend en funktion pr. kolonne for overnavne(df) sapply(df, middelværdi)
Anvend en funktion pr. række for over seq_len(nrow(df)) anvend(df, 1, sum)
Opbyg en liste over resultater for med liste[[i]] <- … lapply(v, f)
Betinget omkodning for med hvis og ellers hvis(kond., a, b)

Når en løkke stadig er det rigtige svar. Behold for-løkken, når hver iteration afhænger af det forrige resultat, når du kalder en ekstern tjeneste eller skriver filer, eller når klarhed er vigtigere end hastighed på et lille objekt.

Hvis du skal loope, så præalloker. Hvis et objekt vokser inde i en løkke, tvinges R til at kopiere det i hver omgang. Opret det først i fuld størrelse:

# 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 Loop i R: Hurtig reference

Hver konstruktion, der bruges i denne vejledning, er anført nedenfor:

Objektiv Code
Loop over en vektor
for (i in v) { print(i) }
Løft sikkert over indekser
for (i in seq_along(v)) { print(v[i]) }
Løkke over en liste
for (p in my_list) { print(p) }
Løkke over datarammekolonner
for (col in names(df)) { print(mean(df[[col]])) }
Loop over en matrix
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c])
Forlad løkken tidligt
if (condition) break
Spring én iteration over
if (condition) next
Forallokér outputtet
out <- numeric(n)

Ofte Stillede Spørgsmål

Når x er tom, returnerer 1:length(x) sekvensen 1, 0, og løkken kører to gange på ikke-eksisterende elementer. seq_along(x) returnerer en tom sekvens, så løkken springes korrekt over.

Selve løkken er ikke problemet. At udvide et objekt indeni den er det, fordi R kopierer hele objektet i hver gennemgang. Foralloker resultatet, eller brug en vektoriseret funktion, og mellemrummet forsvinder stort set.

Kolonner. En dataramme er en liste af kolonner, så hver iteration giver dig én hel kolonne. Brug seq_len(nrow(df)) eksplicit, hvis du i stedet har brug for at gennemgå rækkerne.

For-løkker driver hyperparameter-sweeps, krydsvalideringsfolds og træningsepoker. Hver af disse har et kendt iterationsantal, hvilket er præcis, hvad for-konstruktionen er designet til.

Ja. AI-assistenter kan konvertere de fleste elementvise loops til vektoriserede eller apply-family-ækvivalenter. Sammenlign outputtet fra begge versioner med identical(), før du erstatter originalen.

Opsummer dette indlæg med: