lookup <- c(1,5,10,14,34)
lookup
[1] 1 5 10 14 34
Looping through a vector and doing some task is really useful. However, it can be tricky to avoid getting an error on the last step. Rather than using if...else
in a for
loop, the while
loop works well for this scenario.
Nathan Craig
March 18, 2024
March 21, 2024
Quite often we want to loop through a vector, list, or data frame of objects and do something. Often times we want to do things based on a position or, in this case, a relationship between positions in an index. I recently ran into a situation where I was getting errors while trying to loop through an index and get the values between the two lookups. While all of the individual parts of the expression worked, they returned an error when run through a for loop. I couldn’t figure out why so I started making a reproducible example to ask a question on Stack Overflow. Unsurprisingly I answered my own question in the process. Here’s what happened.
Let’s assume a lookup vector. We’re actually interested in the numbers between the lookup values (i.e. 1-5, 5-10, etc).
lookup <- c(1,5,10,14,34)
lookup
[1] 1 5 10 14 34
We can count through the number of items in the vector, all’s good.
i <- 1
lookup[1]:lookup[i+1]
[1] 1 2 3 4 5
Now let’s take those parts and run them through a loop to get the intergers between the two lookups using a loop. All of the component parts of the loop work, but the output contains an error. After some puzzling time I figured out that it actually works, but fails on the last item because there is no second placeholder when it does lookup[i+1]
on the last item. The print()
function was helpful in diagnosing the issue. It dawned on me that the last item fails because on that last item lookup[i+1]
does not exist because it is outside the length of the list (i.e. (> length(lookup)
).
In the process, I also learned that several people recommend using seq_along()
rather than length()
. There is also seq_len()
for data frames.
After scratching my head and trying to place an an if...else
statement, I realized that while
is a much simpler solution. For the while loop, seq_along()
didn’t work but length()
works fine.
@online{craig2024,
author = {Craig, Nathan},
title = {Simple {Way} to {Deal} with {Loop} {Lengths}},
date = {2024-03-18},
url = {https://ncraig.netlify.app/posts/2024-03-18-loop-lengths/index.html},
langid = {en}
}