R — Loops
The for loop
R's for loop iterates over a sequence:
for (i in 1:5) {
print(i)
}
# 1 2 3 4 5
The loop variable i takes each value in the sequence, one at a time.
Iterating over vectors
fruits <- c("apple", "banana", "cherry")
for (fruit in fruits) {
cat(fruit, "\n")
}
The loop variable can be named anything — item, x, fruit.
Nested loops
for (i in 1:3) {
for (j in 1:3) {
cat(i, "×", j, "=", i * j, "\n")
}
}
The inner loop runs completely for each iteration of the outer loop. Total iterations: 3 × 3 = 9.
While loops
count <- 1
while (count <= 5) {
print(count)
count <- count + 1
}
Always ensure your loop has a clear exit path. Without count <- count + 1, this runs forever.
Repeat loops
R has a repeat loop — like while(TRUE):
repeat {
x <- sample(1:10, 1)
cat(x, " ")
if (x == 7) break
}
repeat runs forever until break is hit. Always include a break condition.
break and next
break exits the loop entirely:
for (i in 1:100) {
if (i == 5) break
print(i)
}
# 1 2 3 4
next skips to the next iteration:
for (i in 1:10) {
if (i %% 2 == 0) next # skip even numbers
print(i)
}
# 1 3 5 7 9
The apply family
R's vectorized approach makes loops less necessary. The apply family functions are preferred:
lapply — apply to each element, return list
numbers <- list(1, 2, 3, 4, 5)
squares <- lapply(numbers, function(x) x^2)
# list(1, 4, 9, 16, 25)
sapply — simplified version, return vector
squares <- sapply(1:5, function(x) x^2)
# 1 4 9 16 25
apply — apply to rows or columns of a matrix
m <- matrix(1:12, nrow = 3)
apply(m, 1, sum) # row sums: 22 26 30
apply(m, 2, mean) # column means: 2 5 8 11
tapply — apply by group
tapply(mtcars$mpg, mtcars$cyl, mean)
# 6 cyl: 19.74
# 4 cyl: 26.66
# 8 cyl: 15.10
vapply — type-safe sapply
vapply(1:5, function(x) x^2, numeric(1))
# Returns a numeric vector with guaranteed type
Common patterns
Accumulator
total <- 0
for (i in 1:100) {
total <- total + i
}
print(total) # 5050
# Or use sum()
print(sum(1:100)) # 5050
Search
numbers <- c(3, 7, 1, 9, 4, 6)
target <- 9
found <- FALSE
for (i in seq_along(numbers)) {
if (numbers[i] == target) {
cat("Found", target, "at position", i, "\n")
found <- TRUE
break
}
}
if (!found) cat(target, "not found\n")
Building a result vector
# Pre-allocate for efficiency
result <- numeric(10)
for (i in 1:10) {
result[i] <- i^2
}
# Or use sapply (preferred)
result <- sapply(1:10, function(x) x^2)
Loops vs apply
# Loop approach
results <- numeric(nrow(mtcars))
for (i in seq_len(nrow(mtcars))) {
results[i] <- mtcars$mpg[i] / mtcars$wt[i]
}
# Vectorized approach (preferred)
results <- mtcars$mpg / mtcars$wt
# Apply approach
results <- apply(mtcars[, c("mpg", "wt")], 1, function(row) row[1] / row[2])
Vectorized operations are almost always faster and more readable than loops in R.
Performance tips
# Bad — growing a vector in a loop
result <- c()
for (i in 1:10000) {
result <- c(result, i^2) # slow — copies every iteration
}
# Better — pre-allocate
result <- numeric(10000)
for (i in 1:10000) {
result[i] <- i^2
}
# Best — vectorized
result <- (1:10000)^2
Using loops with data frames
# Iterate over rows
for (i in 1:nrow(mtcars)) {
cat(mtcars[i, "mpg"], "mpg,", mtcars[i, "hp"], "hp\n")
}
# Iterate over columns
for (col in names(mtcars)) {
cat(col, ":", class(mtcars[[col]]), "\n")
}
Mini Practice
- Use a for loop to calculate the sum of 1 to 100
- Write a while loop that finds the first power of 2 greater than 1000
- Use
sapply()to convert a vector of temperatures from Celsius to Fahrenheit - Use
lapply()to applysummary()to each column ofmtcars - Write a loop that prints the first 20 Fibonacci numbers
Next: packages — extending R →
Related Topics
Frequently Asked Questions about Loops
What is Loops in R?
Loops is a fundamental concept in R. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Loops?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Loops.
Why is Loops important in R?
Loops is essential for R development. Understanding this concept will help you write better code and solve real-world problems more effectively.