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 wherei
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
<- 6 + 2
result <- 8 + 2
result <- 4 + 2
result <- 7 + 2
result <- 11 + 2 result
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:
- The Meat: Write down the code for one version.
<- 6 + 2 result
- The Bread: Embed this code in the loop syntax (
for(i in X){}
)
for(i in X){
<- 6 + 2
result }
- Create a vector that contains the values you want to loop through
<- c(6, 8, 4, 7, 11) somenumbers
- Create a storage vector that will contain the results
<- rep(NA, length(somenumbers)) result
- Modify the meat and bread to iterate by using
[i]
, and replaceX
.
for(i in 1:length(somenumbers)){
<- somenumbers[i] + 2
result[i] }
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)
<- c(6, 8, 4, 7, 11) # iteration vector
somenumbers <- rep(NA, length(somenumbers)) # container vector
result
for(i in 1:length(somenumbers)){
<- somenumbers[i] + 2
result[i]
} 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 oursomenumbers
vectorsomenumbers[1]
, add 2 to it, and store it in the first position of our container vectorresult[1]
. Wheni
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
1] <- somenumbers[1] + 2
result[1] result[
## [1] 8
# Suppose i is 2
2] <- somenumbers[2] + 2
result[2] result[
## [1] 10
# Suppose i is 3
3] <- somenumbers[3] + 2
result[3] result[
## [1] 6
6.1.3 Troubleshooting a loop
The inside part of the loop should run if we set i
to a particular value.
<- 1
i <- somenumbers[i] + 2 result[i]
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!
<- 1
i <- somenumberz[i] + 2 result[i]
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
.
<- c(70, 40, 45, 60, 43, 80, 23) pollresults
Remember the steps:
- The Meat: Write down the code for one version.
- The Bread: Embed this code in the loop syntax (
for(i in X){}
) - Create a vector that contains the values you want to loop through (here it’s
pollresults
) - Create a storage vector that will contain the results (here it’s
adjustedpollresults
) - Modify the meat and bread to iterate by using
[i]
and replaceX
.
Try on your own, then expand for the solution.
<- c(70, 40, 45, 60, 43, 80, 23)
pollresults <- rep(NA, length(pollresults))
adjustedpollresults
for(i in 1:length(pollresults)){
<- (pollresults[i] + 10)/100
adjustedpollresults[i]
} adjustedpollresults
## [1] 0.80 0.50 0.55 0.70 0.53 0.90 0.33