Loops and Apply Functions in R

basics
r-programming
Learn how to use loops and apply functions for efficient data processing in R
Published

March 30, 2025

Loops and Apply Functions in R

R offers several ways to perform repetitive tasks through loops and the more efficient apply family of functions.

For Loops

The for loop iterates over elements in a sequence:

# Basic for loop
for (i in 1:5) {
  print(paste("Iteration:", i))
}
[1] "Iteration: 1"
[1] "Iteration: 2"
[1] "Iteration: 3"
[1] "Iteration: 4"
[1] "Iteration: 5"
# Looping through a vector
fruits <- c("apple", "banana", "cherry")
for (fruit in fruits) {
  print(paste("I like", fruit))
}
[1] "I like apple"
[1] "I like banana"
[1] "I like cherry"

While Loops

The while loop continues until a condition becomes false:

# Basic while loop
counter <- 1
while (counter <= 5) {
  print(paste("Count:", counter))
  counter <- counter + 1
}
[1] "Count: 1"
[1] "Count: 2"
[1] "Count: 3"
[1] "Count: 4"
[1] "Count: 5"

Repeat Loops

The repeat loop runs indefinitely until a break statement:

# Repeat loop with break
counter <- 1
repeat {
  print(paste("Count:", counter))
  counter <- counter + 1
  if (counter > 5) {
    break
  }
}
[1] "Count: 1"
[1] "Count: 2"
[1] "Count: 3"
[1] "Count: 4"
[1] "Count: 5"

Control Statements

Use break to exit a loop and next to skip to the next iteration:

# Using next to skip iterations
for (i in 1:10) {
  if (i %% 2 == 0) {  # Skip even numbers
    next
  }
  print(paste("Odd number:", i))
}
[1] "Odd number: 1"
[1] "Odd number: 3"
[1] "Odd number: 5"
[1] "Odd number: 7"
[1] "Odd number: 9"

Apply Functions

The apply family of functions offers a more efficient and concise way to perform iterations in R.

apply() - For matrices and arrays

# Create a matrix
mat <- matrix(1:9, nrow = 3)
print(mat)
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
# Apply sum function to each row
apply(mat, 1, sum)  # MARGIN=1 for rows
[1] 12 15 18
# Apply mean function to each column
apply(mat, 2, mean)  # MARGIN=2 for columns
[1] 2 5 8

lapply() - For lists, returns a list

# List of vectors
my_list <- list(a = 1:3, b = 4:6, c = 7:9)

# Apply function to each element
lapply(my_list, sum)
$a
[1] 6

$b
[1] 15

$c
[1] 24

sapply() - Simplified apply, returns vector or matrix

# Same as above but with simplified output
sapply(my_list, sum)
 a  b  c 
 6 15 24 
# Using with a custom function
sapply(my_list, function(x) x * 2)
     a  b  c
[1,] 2  8 14
[2,] 4 10 16
[3,] 6 12 18

vapply() - Like sapply but with pre-specified output type

# Specify the output type for safety
vapply(my_list, sum, FUN.VALUE = numeric(1))
 a  b  c 
 6 15 24 

tapply() - Apply function to subsets of a vector

# Vector and grouping factor
values <- c(1, 2, 3, 4, 5, 6, 7, 8)
groups <- c("A", "B", "A", "B", "A", "B", "A", "B")

# Calculate mean by group
tapply(values, groups, mean)
A B 
4 5 

mapply() - Multivariate version of sapply

# Apply function to multiple lists in parallel
mapply(sum, list(1:3), list(4:6), list(7:9))
[1] 45
# Create strings with multiple inputs
mapply(paste, "X", 1:5, "Y", SIMPLIFY = TRUE)
      X    <NA>    <NA>    <NA>    <NA> 
"X 1 Y" "X 2 Y" "X 3 Y" "X 4 Y" "X 5 Y" 

The apply family of functions is generally preferred over loops in R because they are: 1. More concise and readable 2. Often faster for large datasets 3. Aligned with R’s vectorized approach to data processing