Ciclo For in R con esempi di lista e matrice
⚡ Riepilogo intelligente
In R, il ciclo for esegue un blocco di codice una volta per ogni elemento di una sequenza, che si tratti di un vettore, una lista o una matrice. Questa guida illustra ciascuno di questi casi e mostra quando l'utilizzo di un codice vettorializzato rappresenta la scelta migliore.

A per loop Ripete un blocco di codice una volta per ogni elemento di una sequenza. Tale sequenza può essere un vettore, una lista, un data frame, una matrice o qualsiasi altro oggetto su cui R può iterare. R distingue tra maiuscole e minuscole, quindi la parola chiave è sempre in minuscolo. pere le parentesi graffe sono necessarie ogni volta che il corpo del testo si estende su più di una riga.
Sintassi del ciclo for in R
for (i in vector) { Exp }
Qui,
R eseguirà il loop su tutte le variabili in vector ed eseguirà il calcolo scritto all'interno di exp.

Vediamo alcuni esempi.
Ciclo For in R Esempio 1: Iteriamo su tutti gli elementi di un vettore e stampiamo il valore corrente.
# Create fruit vector fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # Create the for statement for ( i in fruit){ print(i) }
Produzione:
## [1] "Apple" ## [1] "Orange" ## [1] "Passion fruit" ## [1] "Banana"
Ciclo For in R Esempio 2: eleva al quadrato ogni numero intero da 1 a 4 e memorizza i risultati in una lista.
# 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)
Produzione:
## [1] 1 4 9 16
I cicli for sono utili nel lavoro di apprendimento automatico. La regolazione di un parametro di regolarizzazione significa testare molti valori candidati e mantenerliping quella che minimizza la funzione di perdita, e un ciclo for è il modo più semplice per esplorare quell'intervallo.
Come utilizzare break e next in un ciclo for
Due parole chiave interrompono la normale sequenza di un ciclo for.
- rompere esce immediatamente dal ciclo e salta ogni elemento rimanente.
- GENERAZIONE abbandona solo l'elemento corrente e passa a quello successivo.
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) }
Nei cicli annidati, break e next agiscono solo sul ciclo più interno che li contiene. Per lasciare entrambi i cicli in sospeso nell'esempio della matrice, imposta una variabile flag e controllala anche nel ciclo esterno.
Utilizzare seq_along() per gli indici. Scrivere for (i in 1:length(x)) sembra innocuo ma fallisce su un oggetto vuoto, perché 1:0 produce la sequenza 1, 0 e il ciclo viene eseguito due volte. seq_along(x) restituisce invece una sequenza vuota, quindi il ciclo viene saltato correttamente:
for (i in seq_along(fruit)) { cat(i, fruit[i], '\n') }
Ciclo For su una lista
gabinettoping su una lista funziona esattamente come il bagnoping su un vettore, con la differenza che ogni elemento può contenere un tipo diverso:
# 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) }
Produzione:
## [1] "Apple" "Orange" "Passion fruit" "Banana" ## [1] 10 12 15 ## [1] FALSE
Ciclo for su una matrice
Una matrice ha due dimensioni, righe e colonne, quindi per iterare su ogni cella sono necessari due cicli for annidati: uno esterno per le righe e uno interno per le colonne.
# 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]))
Produzione:
## [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"
Ciclo for su un DataFrame in R
Un data frame è un elenco di colonne, quindi un semplice ciclo for scorre le sue colonne anziché le sue righe. Questo è generalmente ciò che si desidera:
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') }
Nota la doppia parentesi. df[[col]] extracts restituisce la colonna come un vettore, mentre df[col] restituisce un data frame a una colonna che mean() non è in grado di gestire.
gabinettoping su più righe. L'iterazione riga per riga è possibile ma lenta, perché R copia la riga a ogni passaggio:
for (r in seq_len(nrow(df))) { cat('Row', r, 'sums to', sum(df[r, ]), '\n') }
Per qualsiasi cosa che superi qualche migliaio di righe, preferisci rowSums(df), apply(df, 1, sum) o un dplyr raggruppare per() e riassumere() pipeline, tutte le quali svolgono lo stesso lavoro senza la copia.
Cicli for vs vettorizzazione in R
R è un linguaggio vettorializzato: la maggior parte dei suoi operatori e funzioni agiscono già simultaneamente su interi vettori, nel codice C compilato. Un ciclo esplicito che ripete un'operazione vettorializzata elemento per elemento è sia più lungo che più lento.
# Loop version squares <- c() for (i in 1:4) { squares[i] <- i * i } # Vectorized version, same result squares <- (1:4)^2
| Task | Ciclo continuo | Equivalente vettoriale |
|---|---|---|
| Aritmetica elemento per elemento | per ogni elemento | x * 2, x + y, x^2 |
| Applica una funzione per colonna | per oltre nomi(df) | applica(df, media) |
| Applica una funzione per riga | per oltre seq_len(nrow(df)) | applica(df, 1, somma) |
| Crea un elenco di risultati | per con lista[[i]] <- … | lapply(v, f) |
| Ricodifica condizionale | per con se e altrimenti | ifelse(cond, a, b) |
Quando un ciclo è ancora la risposta giusta. Mantieni il ciclo for quando ogni iterazione dipende dal risultato precedente, quando chiami un servizio esterno o scrivi file, oppure quando la chiarezza è più importante della velocità su un oggetto di piccole dimensioni.
Se è necessario utilizzare un ciclo, preallocate la memoria. Espandere un oggetto all'interno di un ciclo costringe R a copiarlo a ogni passaggio. Crealo prima a dimensioni reali:
# 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
Ciclo For in R: Guida rapida
Di seguito è riportato l'elenco di tutte le strutture utilizzate in questo tutorial:
| Obiettivo | Code |
|---|---|
| Ciclo su un vettore |
for (i in v) { print(i) } |
| Iterare sugli indici in modo sicuro |
for (i in seq_along(v)) { print(v[i]) } |
| Passa il mouse su un elenco |
for (p in my_list) { print(p) } |
| Scorrere le colonne del dataframe |
for (col in names(df)) { print(mean(df[[col]])) } |
| Ciclo su una matrice |
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c]) |
| Esci dal ciclo in anticipo |
if (condition) break
|
| Salta un'iterazione |
if (condition) next
|
| Preassegnare l'output |
out <- numeric(n) |
