Loops — for, while and repeat
The coordinator wants a running total of the harvest, plot by plot, and wants to know how many plots it takes, in order, to reach 30 kg. The first job has a one-word vector answer; the second is a natural loop. Knowing which is which is most of the skill.
The rule
Loop over
seq_along(x), fill a result made in advance, and prefer vectors when possible.
A for loop runs its body once for each element of a vector:
kg <- c(12.5, 8, 15, 3.5, 6)
for (k in kg) {
print(k * 1000) # one line per plot
}When you need the position as well as the value, loop over positions with seq_along(), and create the result vector before the loop so R is not rebuilding it on every pass:
running <- numeric(length(kg)) # 0 0 0 0 0
for (i in seq_along(kg)) {
previous <- if (i == 1) 0 else running[i - 1]
running[i] <- previous + kg[i]
}
running # 12.5 20.5 35.5 39.0 45.0Why seq_along(kg) and not 1:length(kg)? For an empty vector, 1:length(x) is 1:0, which is the two numbers 1 and 0, so the loop runs twice on nothing. seq_along(x) gives no positions at all, so the loop correctly runs zero times.
A while loop repeats as long as its condition is TRUE:
total <- 0
i <- 0
while (total < 30) {
i <- i + 1
total <- total + kg[i]
}
i # 3: plots A, B and C reach 35.5 kgA repeat loop runs until you call break. Inside any loop, break leaves the loop at once and next skips to the next pass.
Many loops are unnecessary in R. kg * 1000 converts every weight without a loop, and cumsum(kg) produces the running total above in one call.
The shortcut
Before writing a loop, ask: "Does each step need the result of the step before?" If not, a vectorised function does the job (kg * 1000, sum(), ifelse()). If it does, as in "keep adding until you reach 30", loop over seq_along() or use while.
Before the loop
totalis 0 andiis 0. Is 0 < 30? Yes, so the body runs.
Drills
Answer fast — trust the rule.
With x <- c(), how many times does for (i in 1:length(x)) run its body?
What is seq_along(c("A", "B", "C"))?
What does next do inside a for loop?
In the while loop from this lesson, if the target were 40 kg instead of 30, what would i be at the end?
Which single call gives the same result as the running loop?
Remember
- Loop over
seq_along(x), fill a result made in advance, and prefer vectors when possible. - Shortcut: does each step need the previous result? No: use a vector function. Yes: loop.
- Trap:
1:length(x)on an empty vector runs twice;breakleaves,nextskips.
