For Loop in R példákkal a listára és a mátrixra

⚡ Okos összefoglaló

Az R-ben a For Loop egy kódblokkot futtat le egyszer egy sorozat minden elemére, legyen az vektor, lista vagy mátrix. Ez a bemutató mindegyiken végigmegy, és megmutatja, mikor a vektorizált kód a jobb választás.

  • 🔁 Alapvető szintaxis: A for (i in vector) { expression } minden elemet sorban az i-hez rendel, és lefuttatja a törzset.
  • 📋 Bármely objektum: Ugyanez a szintaxis végigsétál egy vektoron, egy listán, egy adatkeret oszlophalmazán vagy egy mátrix sorain.
  • 🧮 Beágyazott ciklusok: Egy mátrixnak két ciklusra van szüksége, egy külsőre a sorokhoz és egy belsőre az oszlopokhoz.
  • 🛑 Áramlásszabályozás: A break parancs teljesen kilép a ciklusból, a next pedig csak az aktuális elemet hagyja ki.
  • Vektorizáció először: A beépített vektorizált műveletek és az apply család gyorsabbak és rövidebbek, mint egy explicit ciklus.
  • ⚠️ Biztonságos szekvenciák: Használd a seq_along(x) függvényt az 1:length(x) helyett, ami hibásan viselkedik, ha az objektum üres.

Ciklus R listamátrixban

A hurokhoz Egy kódblokkot egyszer ismétel egy sorozat minden eleméhez. Ez a sorozat lehet vektor, lista, adatkeret, mátrix vagy bármilyen más objektum, amelyen az R végig tud iterálni. Az R megkülönbözteti a kis- és nagybetűket, így a kulcsszó mindig kisbetűs. mert, és a kapcsos zárójelekre akkor van szükség, ha a törzs egynél több soron átível.

Ciklus szintaxis R-ben

for (i in vector) {
    Exp
}

Itt,

R végighurkolja a vektor összes változóját, és elvégzi az exp-be írt számítást.

For Loop in R
For Loop in R

Lássunk néhány példát.

For Loop in R 1. példa: Iteráljuk a vektor összes elemét, és kinyomtatjuk az aktuális értéket.

# 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 2. példaEmeljünk négyzetre minden 1-től 4-ig terjedő egész számot, és tároljuk az eredményeket egy listában.

# 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

A for ciklusok hasznosak a gépi tanulásban. Egy regularizációs paraméter hangolása azt jelenti, hogy sok jelölt értéket tesztelünk, és megtartjuk aping az, amelyik minimalizálja a veszteségfüggvényt, és egy for ciklus az egyszerű módja ennek a tartománynak a seperésére.

Hogyan használjuk a break és a next függvényeket egy For ciklusban?

Két kulcsszó megszakítja a for ciklus normál sorrendjét.

  • szünet azonnal kilép a ciklusból, és kihagyja az összes fennmaradó elemet.
  • következő csak az aktuális elemet hagyja el, és a következőre ugrik.
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)
}

Beágyazott ciklusokban a break és a next act utasításokat csak a legbelső, őket tartalmazó cikluson kell végrehajtani. Ha mindkét ciklust a mátrixpéldában szeretnéd hagyni, állíts be egy jelzőváltozót, és teszteld azt a külső ciklusban is.

Indexekhez használd a seq_along() függvényt. Az (i in 1:length(x)) függvény írása ártalmatlannak tűnik, de üres objektumon hibát jelez, mivel az 1:0 az 1, 0 szekvenciát eredményezi, és a ciklus kétszer fut le. A seq_along(x) egy üres szekvenciát ad vissza, így a ciklus helyesen kimarad:

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

Ciklus egy listán keresztül

Vécéping egy lista felett pontosan úgy működik, mint a WCping egy vektor felett, azzal a különbséggel, hogy minden elem más típust viselhet:

# 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

Mátrix feletti ciklushoz

Egy mátrixnak két dimenziója van, sorai és oszlopai, így minden cellán végigiteráláshoz két egymásba ágyazott for ciklusra van szükség: egy külsőre a soroknak és egy belsőre az oszlopoknak.

# 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" 

Ciklus egy adatkeret felett R-ben

Egy adatkeret oszlopok listája, tehát egy egyszerű for ciklus inkább az oszlopait, mint a sorait járja be. Általában erre van szükség:

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

Figyeljük meg a dupla zárójelet. df[[col]] extracA `ts` függvény vektorként kezeli az oszlopot, míg a df[col] függvény egy egyoszlopos adatkeretet ad vissza, amelyet a mean() függvény nem tud kezelni.

Vécéping sorok felett. A soronkénti iteráció lehetséges, de lassú, mivel az R minden menetben másolja a sort:

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

Néhány ezer soron túli mennyiség esetén a rowSums(df), apply(df, 1, sum) vagy dplyr függvények használata javasolt. group_by() és summarize() pipeline, amelyek mindegyike ugyanazt a munkát végzi másolás nélkül.

Ciklusok vs. vektorizáció R-ben

Az R egy vektorizált nyelv: operátorainak és függvényeinek többsége már eleve teljes vektorokra hat egyszerre, a lefordított C kódban. Egy explicit ciklus, amely egy vektorizált műveletet elemről elemre ismétel, hosszabb és lassabb is.

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

# Vectorized version, same result
squares <- (1:4)^2
Feladat Hurok Vektorizált megfelelője
Elemenkénti aritmetika minden elem felett x * 2, x + y, x^2
Függvény alkalmazása oszloponként over names(df) esetén sapply(df, átlag)
Függvény alkalmazása soronként seq_len(nrow(df)) felett apply(df, 1, összeg)
Készítsen egy listát az eredményekről a következővel: lista[[i]] <- … lapply(v, f)
Feltételes átkódolás mert if és else esetén ifelse(feltétel, a, b)

Amikor a ciklus továbbra is a helyes válasz. Tartsd meg a for ciklust, ha minden iteráció az előző eredménytől függ, ha külső szolgáltatást hívsz meg vagy fájlokat írsz, vagy ha egy kis objektumon az érthetőség fontosabb, mint a sebesség.

Ha ciklust kell létrehozni, akkor előre kell lefoglalni. Egy objektum cikluson belüli növekedése arra kényszeríti az R-t, hogy minden menetben másolja azt. Először teljes méretben hozza létre:

# 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

Ciklus R-ben: Gyorsreferencia

Az oktatóanyagban használt összes konstrukció az alábbiakban felsorolásra kerül:

Objektív Code
Ciklus egy vektor felett
for (i in v) { print(i) }
Indexek biztonságos átfutása
for (i in seq_along(v)) { print(v[i]) }
Lista végigjátszása
for (p in my_list) { print(p) }
Adatkeret oszlopainak cikluson keresztüli átvitele
for (col in names(df)) { print(mean(df[[col]])) }
Ciklus egy mátrix felett
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c])
Lépj ki a ciklusból korán
if (condition) break
Egy iteráció kihagyása
if (condition) next
A kimenet előzetes kiosztása
out <- numeric(n)

GYIK

Amikor x üres, az 1:length(x) függvény az 1, 0 sorozatot adja vissza, és a ciklus kétszer fut le nem létező elemeken. A seq_along(x) függvény egy üres sorozatot ad vissza, így a ciklus helyesen kimarad.

Maga a ciklus nem a probléma. Egy benne lévő objektum növesztése az, mivel az R minden menetben lemásolja az egész objektumot. Ha előre kiosztjuk az eredményt, vagy vektorizált függvényt használunk, a rés nagyrészt eltűnik.

Oszlopok. Egy adatkeret oszlopok listája, így minden iteráció egy teljes oszlopot ad vissza. Ha a sorokat kell bejárnod, használd explicit módon a seq_len(nrow(df)) függvényt.

A for ciklusok hiperparaméter-söpréseket, keresztvalidációs hajtásokat és betanítási korszakokat vezérelnek. Mindegyikhez tartozik egy ismert iterációs szám, ami pontosan az, amire a for konstrukció készült.

Igen. A mesterséges intelligencia asszisztensek a legtöbb elemenkénti ciklust vektorizált vagy apply-családba tartozó megfelelővé alakíthatják. Hasonlítsa össze mindkét verzió kimenetét az identical() függvénnyel, mielőtt lecserélné az eredetit.

Foglald össze ezt a bejegyzést a következőképpen: