# 17 Iterations: While Loop

In the previous chapter you got introduced to your first iterative construct:
`for`

loops. You use this type of loop when you know how many times a
given computation needs to be repeated. But what about those situations in
which you have to repeat a process without necessarily knowing how many times
this repetition will take place? This is where we need a more general type of
loop, namely, the **while** loop.

## 17.1 Motivation

Let’s begin with the same toy example discussed in the previous chapter.
Say you have a vector `vec <- c(3, 1, 4)`

, and suppose you want to obtain a new
vector `vec2`

that adds 1 to every element in `vec`

. You know that this can
easily be achieved using vectorized code:

```
<- c(3, 1, 4)
vec
<- vec + 1
vec2
vec2> [1] 4 2 5
```

Again, in order to explain the concept of a `while`

loop, I am going to ask
you to pretend that R does not have vectorized code.

What would you need to do in order to add 1 to the elements in `vec`

? As we
mentioned in the preceding chapter, you would need to do something like this:

```
# new vector to be updated
<- rep(0, 3)
vec2
# repetitive steps
1] <- vec[1] + 1
vec2[2] <- vec[2] + 1
vec2[3] <- vec[3] + 1 vec2[
```

That is, take the first element in `vec`

and add 1, then take the second element
in `vec`

and add 1, and finally the third element in `vec`

and add 1. Basically,
you are performing the same type of operation several times: selecting an
element in `vec`

and adding 1 to it. But there’s a lot of (unnecessary) repetition.

We’ve seen how to write a `for`

loop to take care of the addition computation.
Alternatively, we can also approach this problem from a slightly different
perspective by considering a **stopping condition** to decide when to terminate
the repetitive process of adding 1 to the elements in `vec`

.

What stopping condition can we use? Well, one example may involve: “let’s keep
selecting a single element in `vec`

and adding 1 to it, until we *exhaust*
all elements in `vec`

”. In other words, let’s keep iterating until we reach the
last element in `vec`

.

As usual, the first step involves identifying the common structure of the
repetitive steps. We can make the repetitive code a bit more general by
referring to each position as `pos`

:

`<- vec[pos] + 1 vec2[pos] `

Once we have the correct abstraction for the code that needs to be repetead,
then we can encapsulate it with a `while`

loop. Let me first show you an
example and then we’ll examine it in detail:

```
# input vector
<- c(3, 1, 4)
vec
# initialize output vector
<- rep(0, 3)
vec2
# declare auxiliary iterator
<- 1
pos
# while loop
while (pos <= length(vec)) {
<- vec[pos] + 1
vec2[pos] <- pos + 1 # update iterator
pos }
```

The first thing that I should mention is that writing an R `while`

loop is a
bit more complex than writing a `for`

loop. The complexity has to do with some
of the things that R does not automatically take care of in a `while`

loop.

One main difference between a `for`

loop and a `while`

loop is that in the
latter we must explicit declare the auxiliary iterator and give it an initial
value: `pos <- 1`

.

Next we have the `while`

statement. This statement is technically a function,
but I prefer to think of it, and call it, a statement (like the `if`

and the
`for`

statements). What you pass inside parenthesis of the `while`

declaration
is a **condition**. This is basically any piece of code that R will evaluate
and coerce it into a logical condition that is `TRUE`

or `FALSE`

. The `while`

loop iterates as long as the condition is `TRUE`

. If the condition becomes
`FALSE`

then the loop is terminated.

The code of the repetitive steps consists of an R expression `{ ... }`

. This
is where we indicate what to do at each step. Often, an important piece of
code that we need to include here involves increasing the value of
the auxiliary iterator: `pos <- pos + 1`

. In this particular example, if we
don’t increase the iterator `pos`

, the loop would iterate forever.

Note that the condition is the **stopping condition**, which in turn depends
on the auxiliary iterator: `pos <= length(vec)`

. You can think of this
condition as: “let’s keep iterating until we reach the last element in `vec`

”.

## 17.2 Anatomy of a While Loop

Now that you’ve seen a first example of a `while`

loop, I can give you a
generic template for this kind of iterative construct:

```
<- initial
iterator
while (condition) {
do_something<- iterator + 1
iterator }
```

What’s going on?

you need to declare the auxiliary iterator with some initial value

you declare the

`while`

statement by giving a condition inside parenthesisthe condition must be a piece of code that gets evaluated into a single logical value:

`TRUE`

or`FALSE`

the condition is used as the stopping condition: if the condition is

`TRUE`

the loop keeps iterating; when the condition becomes`FALSE`

the loop is terminatedwe use an R compound expression

`{ ... }`

to embrace the code that will be repeated at each iterationinside the loop, you typically need to increase the value of the

`iterator`

; even if the`condition`

does not depend on the`iterator`

, it’s a good idea to keep track of the number of iterations in the loop

## 17.3 Another Example

Let’s see a more interesting example.

Say we generate a vector with 10 different integer numbers between 1 and 100,
arranged in increasing order. To make things more interesting, we are going to
generate these numbers in a random way using the `sample.int()`

function that
allows us to get a random sample of `size = 10`

integers, sampling without
replacement (`replace = FALSE`

):

```
set.seed(234) # for replication purposes
# vector of 10 random integers between 1 and 100
= sample.int(n = 100, size = 10, replace = FALSE)
random_numbers = sort(random_numbers)
random_numbers
random_numbers> [1] 1 18 31 34 46 56 68 92 97 98
```

What are we going to do with these `random_numbers`

? We are going to compute
a cumulative sum until its value becomes greater than 100. And we are going
to consider these two questions:

What is the value of the cumulative sum?

How many numbers were added to reach the sum’s value?

My recommendation is to always start with baby steps. Simply put, start writing code for a couple of concrete steps so that you understand what kind of computations will be repeated, and what things they have in common:

```
# initialize output sum
= 0
total_sum
# accumulate numbers
= total_sum + random_numbers[1]
total_sum = total_sum + random_numbers[2]
total_sum = total_sum + random_numbers[3]
total_sum # ... keep adding numbers as long as total_sum <= 100
```

There are three important aspects to keep in mind:

we need an object to store the cumulative sum:

`total_sum`

we need an iterator to move through the elements of

`random_numebrs`

and of course we need to determine a stopping-condition:

`total_sum <= 100`

Here’s the code:

```
# initialize object of cumulative sum
= 0
total_sum
# declare iterator
= 0
pos
# repetitive steps
while (total_sum <= 100) {
= pos + 1
pos = total_sum + random_numbers[pos]
total_sum
}
# what is the value of the cumulative sum?
total_sum> [1] 130
# how many iterations were necessary?
pos> [1] 5
```

Observe that in this example, we declared `pos = 0`

. Then, at each iteration,
we increase its value `pos = pos + 1`

, and then we added `random_numbers[pos]`

to the previous `total_sum`

value, effectively updating the cumulative sum.

For comparison purposes, consider this other `while`

loop. It looks extremely
similar to the preceding loop but there is an important difference.

```
# initialize object of cumulative sum
= 0
total_sum
# declare iterator
= 1
pos
# repetitive steps
while (total_sum <= 100) {
= total_sum + random_numbers[pos]
total_sum = pos + 1
pos
}
# what is the value of the cumulative sum?
total_sum> [1] 130
# how many iterations were necessary?
pos> [1] 6
```

Can you see the difference between these two `while`

loops?

In this second loop, the iterator is declared as `pos = 1`

, and its value is
increased after updating the cumulative sum. While `total_sum`

has the correct
value, `pos`

does not indicate anymore the right number of iterations.

I wanted to show you this second example to make a point: in a `while`

loop
you not only need to declare the iterator before entering the loop, but you
also need to carefully think what initial value you’ll use, as well as when
to increase its value inside the loop. Some times the very first thing to do
in each iteration is to increase the value of the iterator; some times that’s
the last thing to do. It all depends on the specific way you are approaching
a given iterative task.

### 17.3.1 While Loops and Next statement

Sometimes we need to skip a certain iteration if a given condition is met, this
can be done with the `next`

statement. The following code chunk contains an
abstract template that uses `next`

:

```
<- initial
iterator
while (condition) {
do_somethingif (skip_condition) {
next
}<- iterator + 1
iterator }
```

As a less abstract example, let’s bring back the while loop of the cumulative
sum of random numbers, but this time say we want to skip any numbers between
30 and 39. This means we need an `if-else`

statement to check whether a
given element of `random_numbers`

is between 30 and 39. If yes, we should
skip that element and go to the `next`

iteration. Here is how to do it:

```
= 0
total_sum = 0
pos
while (total_sum <= 100) {
= pos + 1
pos if (random_numbers[pos] %in% 30:39) {
next
}= total_sum + random_numbers[pos]
total_sum
}
total_sum> [1] 121
pos> [1] 6
```

### 17.3.2 While Loops and Break statement

In addition to skipping certain iterations, sometimes we need to stop a loop
from iterating if a given condition is met. This can be done with the `break`

statement, which is shown below in an abstract code template:

```
while (condition) {
expr1
expr2if (stop_condition) {
break
}
expr3
expr4 }
```

Let’s go back to the cumulative sum example. Say we want to stop iterating
if numbers are greater than or equal to 40. Like we did previously, we need
again an `if-else`

statement to check whether a given element of
`random_numbers`

is greater than or equal to 40. If yes, we stop the loop
from iterating by using the `break`

statement as follows:

```
= 0
total_sum = 0
pos
while (total_sum <= 100) {
= pos + 1
pos if (random_numbers[pos] >= 40) {
break
}= total_sum + random_numbers[pos]
total_sum
}
total_sum> [1] 84
pos> [1] 5
```