Introduction to R: Lecture 10

Topics: Writing Loops Part 1

Sabrina Nardin, Summer 2025

Agenda

  1. For Loops: Introduction
  2. Tracking and Saving For Loop Output
  3. Looping Over Elements vs. Indexes

These slides were last updated on July 30, 2025

1. For Loops: Introduction

What Are Control Structures?

Control structures let us write code that can:

  • Make decisions
    → with conditional statements (if, if...else, etc.)

  • Repeat actions
    → with loops (for, while)

Today we focus on loops, and specifically on “For loops”!

Definition of For Loops

“For loops” are the most common looping construct in many programming languages. They are used to iterate over the elements of an object (usually a list or vector) and perform an action on each one.

Syntax:

for (item in sequence of items) {
  action to be repeated for each item   
}

Example:

for (item in c(1,2,3)) {
  print(item)
}

Simple Example

for (item in c(1,2,3)) {
  print(item)
}

Let’s break this code down:

  • The repeated action here is simple: print(item)

  • item is a placeholder: its value changes with each loop iteration

  • the number of times the statement block repeats depends on the number of items in the sequence — in this example: three items, thus three times

Nested For Loops

For loops can be nested, so the outer loop controls how many times the entire inner loop runs from start to finish:

for (i in c(1,2,3)) {
  print(i)
  for (j in c("cat", "dog", "squirrel", "rabbit")) {
    print(j)
  }
}

Let’s break this code down:

  • The outer loop runs 3 times

  • For each execution of the outer loop, the inner loop runs 4 times

  • That’s a total of 3 × 4 = 12 inner loop outputs, plus 3 outer loop prints

2. Tracking and Saving For Loop Output

Tracing Execution in a For Loop

Observe this code. What does this code output in each run?

for (i in c(1,2,3)) {
  print(i)
  print("Hello")
  my_sum <- 100 + i
  print(my_sum)
}


💻 Try changing the code and predict what happens (clear the environment before each run):

  • Add another print(my_sum) before my_sum <- 100 + i
  • After the last print(my_sum) add these two lines: my_sum <- 1000 and print(my_sum)
  • Modify these two new lines into: my_sum <- 1000 + my_sum and print(my_sum)
  • Change anything else you’re curious about and see what happens!


Tracing Execution in a For Loop

This code defines the my_sum variable outside the loop, before it starts. What does this code output in each run?

my_sum <- 0

for (i in c(1,2,3)) {
  print(i)
  print("Hello")
  my_sum <- my_sum + i
  print(my_sum)
}


💻 Try changing the code and predict what happens (clear the environment before each run):

  • Change my_sum <- 0 to my_sum <- 100
  • Move my_sum <- 0 inside the loop, after the first two print statements
  • Put my_sum <- 0 back outside the loop, and comment out my_sum <- my_sum + i
  • Change anything else you’re curious about and see what happens!


Accumulating a Running Total

What we just observed is a simple example of a common task: accumulating a running total. Use it when you are adding up scores, votes, or counts one at a time, and want to keep track of how the total grows after each loop.

Same code, but with clearer print statements to make each step easier to follow:

my_sum <- 0

for (i in c(1,2,3)) {
  print(paste("Current i is", i))
  print("Hello")
  my_sum <- my_sum + i
  print(paste("Current sum is", my_sum))
}

my_sum

Saving Results from For Loop

The previous code prints the updated sum each time, but only saves the final value. To save all intermediate values, we need to store them in a vector:

my_sum <- 0
output <- vector(mode = "integer", length = 3)

for (i in c(1,2,3)) {
  print(paste("Current i is:", i))
  print("Hello")
  my_sum <- my_sum + i
  print(paste("Current sum is:", my_sum))
  output[i] <- my_sum     # saves sum in position i
}

output

Why output[i] <- my_sum?

When i = 1, my_sum = 0 + 1 = 1 → store 1 in output[1] → output becomes: 1 0 0
When i = 2, my_sum = 1 + 2 = 3 → store 3 in output[2] → output becomes: 1 3 0
When i = 3, my_sum = 3 + 3 = 6 → store 6 in output[3] → output becomes: 1 3 6

This saves the running total at each position i in the vector output.

Saving Results from a For Loop

Our current code works but it’s NOT yet optimal:

  • It only behaves correctly because the input vector is exactly c(1, 2, 3)
  • If the values in the vector change, the current loop may produce incorrect or unexpected results

💻 Try this:

Take the code from the previous slide and change the input vector to c(1, 4, 6) and observe what happens to the output. Can you explain why the result changes?

Saving Results from a For Loop

my_sum <- 0
output <- vector(mode = "integer", length = 3)

for (i in c(1, 4, 6)) {
  print(paste("Current i is:", i))
  print("Hello")
  my_sum <- my_sum + i
  print(paste("Current sum is:", my_sum))
  output[i] <- my_sum  # saves sum in position i
}

output

What Happens in Each Iteration

When i = 1my_sum = 0 + 1 = 1 → store 1 in output[1] → output becomes: 1 0 0

When i = 4my_sum = 1 + 4 = 5 → store 5 in output[4] → output becomes: 1 0 0 5

When i = 6my_sum = 5 + 6 = 11 → store 11 in output[6] → output becomes: 1 0 0 5 NA 11

R won’t throw an error if you assign to an index beyond a vector’s original length: it silently extends the vector, which can lead to unexpected results.

3. Looping Over Elements vs. Indexes

Elements vs. Indexes: Why It Matters

To fix the previous code we need to understand the difference between looping over elements and over indexes:

# Looping over values/elements
x <- c(1, 4, 6)
for (i in x) {
  print(i)        # value
}

# Looping over indexes (method 1)
x <- c(1, 4, 6)
for (i in 1:length(x)) {
  print(i)        # index
  print(x[i])     # value at that index
}

# Looping over indexes (method 2)
x <- c(1, 4, 6)
for (i in seq_along(x)) {
  print(i)
  print(x[i])
}

i and x[i]

Note: i is the loop index or “counter” and should always go 1, 2, 3, 4, etc., while x[i] is the element or value of the vector x at position i and can be any value

Elements vs. Indexes: Why It Matters

Let’s see what happens when we save the output instead of just printing:

❌ Version A

x <- c(1, 4, 6)
my_sum <- 0
output <- vector(mode = "integer", 
                 length = length(x))

# looping over elements
for (i in x) {
  print(paste("Current i is:", i))
  my_sum <- my_sum + i
  print(paste("Current sum is:", my_sum))
  output[i] <- my_sum
}

output

✅ Version B

x <- c(1, 4, 6)
my_sum <- 0
output <- vector(mode = "integer", 
                 length = length(x))

# looping over indexes
for (i in seq_along(x)) {
  print(paste("Current i is:", i))
  my_sum <- my_sum + x[i]
  print(paste("Current sum is:", my_sum))
  output[i] <- my_sum
}

output

Best Practice: Loop Over Indexes

Loop over indexes, like i in 1:length(x) or seq_along(x), instead of elements/values to:

  • Modify, save, or assign values by position (e.g., output[i] <- ...)
  • Ensure your loop works regardless of the values in the vector (e.g., if values repeat or are not valid indices)
  • Have you full control over both: the position i and the value at that position x[i]

💻 Practice: Fix this For Loop

You are a farmer writing a for loop to track tomatoes sold over three days. You want to add up the number of tomatoes sold and store the running total in a vector called output. But something is wrong with the code — can you fix it? First, think about what the output vector should be, then check the code to see what’s going wrong.

tomatoes <- c(10, 2, 100) 
s <- 0
output <- vector(mode = "integer", 
                 length = length(tomatoes))

for (i in seq_along(tomatoes)) {
  print(paste("Current i is:", i))
  s <- s + i
  print(paste("Current sum is:", s))
  output[i] <- s
}

output

Recap: What We Learned Today

  • How for loops work and how to trace what happens at each iteration
  • How to track and save values (like running totals) during a for loop
  • Why it’s important to loop over indexes instead of elements when saving or modifying values
  • Common mistakes with loop output and how to fix them

To print these slides as pdf

Click on the icon bottom-right corner > Tools > PDF Export Mode > Print as a Pdf