6.1 The anatomy of a loop

In many situations, we want to repeat the same calculations with different inputs. Loops allow you to avoid writing many similar code chunks.

  • The function for(i in X){}} will create a loop in your programming code where i is a counter and
  • X is a placeholder for a vector for the possible values of the counter.

We use the following syntax:

for (i in X) {

command1...

command2...

...

}

to indicate we want to repeat command1 and command2 and …. as many commands as we want, for each i in the set of possible values for i stored in X.

6.1.1 The key parts of a loop

The meat: the command or set of commands you want to do over and over.

## the meat
result <- 6 + 2
result <- 8 + 2
result <- 4 + 2
result <- 7 + 2
result <- 11 + 2

Note the pattern: we take some number and + 2 each time.

  • It is the number that is changing -> what we will iterate.

For a loop, you want to:

  1. The Meat: Write down the code for one version.
result <- 6 + 2
  1. The Bread: Embed this code in the loop syntax (for(i in X){})
for(i in X){
    result <- 6 + 2
    }
  1. Create a vector that contains the values you want to loop through
somenumbers <- c(6, 8, 4, 7, 11)
  1. Create a storage vector that will contain the results
result <- rep(NA, length(somenumbers))
  1. Modify the meat and bread to iterate by using [i], and replace X.
for(i in 1:length(somenumbers)){
  result[i] <- somenumbers[i] + 2
}
  where `1:length(somenumbers)` reflects possible values `i` will take 
1:length(somenumbers)
## [1] 1 2 3 4 5

6.1.2 A short example

Let’s put these parts together:

Suppose we want to add 2 to a set of numbers c(6, 8, 4, 7, 11)

somenumbers <- c(6, 8, 4, 7, 11) # iteration vector
result <- rep(NA, length(somenumbers)) # container vector

for(i in 1:length(somenumbers)){
  result[i] <- somenumbers[i] + 2
}
result
## [1]  8 10  6  9 13

How does this work? Every iteration, the value of i changes.

  • For example, when i is 1, we take the first value in our somenumbers vector somenumbers[1], add 2 to it, and store it in the first position of our container vector result[1]. When i is 2, we switch the number in the brackets to 2, corresponding to the second entry in each vector, and so on.
# Suppose i is 1
result[1] <- somenumbers[1] + 2
result[1]
## [1] 8
# Suppose i is 2
result[2] <- somenumbers[2] + 2
result[2]
## [1] 10
# Suppose i is 3
result[3] <- somenumbers[3] + 2
result[3]
## [1] 6

6.1.3 Troubleshooting a loop

The inside part of the loop should run if we set i to a particular value.

i <- 1
result[i] <- somenumbers[i] + 2

If you get an error here, there is something wrong with the meat! (and not necessarily the loop)

result[i]
## [1] 8

For example, if we had a typo, we’d get an error. Try running the below!

i <- 1
result[i] <- somenumberz[i] + 2

6.1.4 Your turn

Using a loop, for each value in our poll results, add 10 and divide by 100. Store in a vector called adjustedpollresults.

pollresults <- c(70, 40, 45, 60, 43, 80, 23)

Remember the steps:

  1. The Meat: Write down the code for one version.
  2. The Bread: Embed this code in the loop syntax (for(i in X){})
  3. Create a vector that contains the values you want to loop through (here it’s pollresults)
  4. Create a storage vector that will contain the results (here it’s adjustedpollresults)
  5. Modify the meat and bread to iterate by using [i] and replace X.
Try on your own, then expand for the solution.
pollresults <- c(70, 40, 45, 60, 43, 80, 23)
adjustedpollresults <- rep(NA, length(pollresults))

for(i in 1:length(pollresults)){
  adjustedpollresults[i] <- (pollresults[i] + 10)/100 
}
adjustedpollresults
## [1] 0.80 0.50 0.55 0.70 0.53 0.90 0.33