For Loop in R with Examples for List and Matrix
โก Smart Summary
For Loop in R runs a block of code once for every element of a sequence, whether that sequence is a vector, a list, or a matrix. This walkthrough iterates over each of them and shows when vectorized code is the better choice.

A for loop repeats a block of code once for every element of a sequence. That sequence can be a vector, a list, a data frame, a matrix, or any other object R can iterate over. R is case-sensitive, so the keyword is always lowercase for, and the curly braces are required whenever the body spans more than one line.
For Loop Syntax in R
for (i in vector) { Exp }
Here,
R will loop over all the variables in vector and do the computation written inside the exp.

Let’s see a few examples.
For Loop in R Example 1: We iterate over all the elements of a vector and print the current value.
# 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 Example 2: square every integer from 1 to 4 and store the results in a list.
# 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 loops are useful in machine learning work. Tuning a regularization parameter means testing many candidate values and keeping the one that minimises the loss function, and a for loop is the straightforward way to sweep that range.
How to Use break and next in a For Loop
Two keywords interrupt the normal sequence of a for loop.
- break exits the loop immediately and skips every remaining element.
- next abandons the current element only and moves on to the following one.
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 nested loops, break and next act only on the innermost loop that contains them. To leave both loops in the matrix example, set a flag variable and test it in the outer loop as well.
Use seq_along() for indexes. Writing for (i in 1:length(x)) looks harmless but fails on an empty object, because 1:0 produces the sequence 1, 0 and the loop runs twice. seq_along(x) returns an empty sequence instead, so the loop is correctly skipped:
for (i in seq_along(fruit)) { cat(i, fruit[i], '\n') }
For Loop Over a List
Looping over a list works exactly like looping over a vector, except that each element can hold a different 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 Loop Over a Matrix
A matrix has two dimensions, rows and columns, so iterating over every cell needs two nested for loops: an outer one for the rows and an inner one for the columns.
# 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 a Data Frame in R
A data frame is a list of columns, so a plain for loop walks its columns rather than its rows. That is usually what you want:
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') }
Note the double bracket. df[[col]] extracts the column as a vector, whereas df[col] returns a one-column data frame that mean() cannot handle.
Looping over rows. Row-wise iteration is possible but slow, because R copies the row on every pass:
for (r in seq_len(nrow(df))) { cat('Row', r, 'sums to', sum(df[r, ]), '\n') }
For anything beyond a few thousand rows, prefer rowSums(df), apply(df, 1, sum), or a dplyr group_by() and summarise() pipeline, all of which do the same work without the copying.
For Loops vs Vectorization in R
R is a vectorized language: most of its operators and functions already act on whole vectors at once, in compiled C code. An explicit loop that repeats a vectorized operation element by element is both longer and slower.
# Loop version squares <- c() for (i in 1:4) { squares[i] <- i * i } # Vectorized version, same result squares <- (1:4)^2
| Task | Loop | Vectorized equivalent |
|---|---|---|
| Element-wise arithmetic | for over each element | x * 2, x + y, x^2 |
| Apply a function per column | for over names(df) | sapply(df, mean) |
| Apply a function per row | for over seq_len(nrow(df)) | apply(df, 1, sum) |
| Build a list of results | for with list[[i]] <- … | lapply(v, f) |
| Conditional recoding | for with if and else | ifelse(cond, a, b) |
When a loop is still the right answer. Keep the for loop when each iteration depends on the previous result, when you are calling an external service or writing files, or when clarity matters more than speed on a small object.
If you must loop, preallocate. Growing an object inside a loop forces R to copy it on every pass. Create it at full size first:
# 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 in R: Quick Reference
Every construct used in this tutorial is listed below:
| Objective | Code |
|---|---|
| Loop over a vector |
for (i in v) { print(i) } |
| Loop over indexes safely |
for (i in seq_along(v)) { print(v[i]) } |
| Loop over a list |
for (p in my_list) { print(p) } |
| Loop over data frame columns |
for (col in names(df)) { print(mean(df[[col]])) } |
| Loop over a matrix |
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c]) |
| Exit the loop early |
if (condition) break
|
| Skip one iteration |
if (condition) next
|
| Preallocate the output |
out <- numeric(n) |
