Loops let us tell R to run a series of commands multiple times. R has two types of loops: while and for.

While Loops

A while loop performs a task until a particular condition is no longer met.

while( condition ){
  this
  code 
  chunk
  will 
  not
  run
}

With while loops, it is very important to make sure that something in the loop will cause the condition to (eventually) become FALSE! Otherwise your loop will continue to run forever.

This loop saves the first 20 Fibonacci numbers:

fibs <- c(0, 1)
itr <- 2

while(itr <= 20){ 
  itr <- itr+1
  fibs <- append(fibs, fibs[itr-1]+fibs[itr-2])
}
fibs
##  [1]    0    1    1    2    3    5    8   13   21   34   55   89  144  233  377
## [16]  610  987 1597 2584 4181 6765

Note that if the condition is false at the start, the loop will never run.

x <- 0
while(x == 2){
  print("loops")
}

Another thing that can be frustrating about while loops is that they don’t stop as soon as the condition becomes false, they stop when the condition is false AND the commands within the loop reach the end. Say I want to print out all Fibonacci numbers under 200. I might try:

fibs <- c(0, 1)
itr <- 2

while(fibs[itr] < 200){ # while(fibs[itr] + fibs[itr-1] < 200){ # 
  itr <- itr+1
  fibs <- append(fibs, fibs[itr-1]+fibs[itr-2])
}
fibs
##  [1]   0   1   1   2   3   5   8  13  21  34  55  89 144 233

But this condition is only false after I’ve hit the number 233, which has already been added to the vector. This needs to be reworked in order to run properly.

On Your Own

Use a while loop to print out 5, then 4, then 3, then 2, then 1.

x <- 5

# while loop

For Loops

The for statement in R is more flexible than in other programming languages. It will iterate over any type of items in a vector or list (in the order they appear in the vector).

for(var in iterable){
  this
  code 
  chunk
  will 
  not
  run
}

Here, var is the variable that takes on - one-by-one - the items in iterable.

Iterature through a vector:

# Iterate through a vector
colors <- c("red","green","blue","yellow")

for (x in colors) {
  print(x)
}
## [1] "red"
## [1] "green"
## [1] "blue"
## [1] "yellow"

Iterate through a list:

lst <- list(3.14, "Hi", c(1,2,3))

for (i in lst) {
  print(i)
}
## [1] 3.14
## [1] "Hi"
## [1] 1 2 3

Print ‘Hello!’ 3 times using a sequence:

for (x in 1:3) {
  print("Hello!")
}
## [1] "Hello!"
## [1] "Hello!"
## [1] "Hello!"

Use another type of sequencing:

for (x in seq(from=2,to=8,by=2)) {
  print(x^2)
}
## [1] 4
## [1] 16
## [1] 36
## [1] 64

Different people have different needs and preferences, but when I have to write a loop, I almost always find myself writing for loops over a sequence of numbers.

On Your Own

Use a for loop to store the first 10 Fibonacci numbers in a vector, fibs. You may want to use the first while loop example to get started.

fibs <- numeric(10) # empty numeric vector of length 10

## For loop goes here ## 

Breaks

The break statement is used to exit the loop immediately. The program continues after the loop.

x <- 5

# If statement starts as TRUE,  the loop will never run 
while (x != 0 ) {
  print(x)
  x = x - 1
  
  if(x == 2){
    print("Entered IF statement, stop loop")
    break 
  }
  
}
## [1] 5
## [1] 4
## [1] 3
## [1] "Entered IF statement, stop loop"

If not given an adequate stopping criteria or break statement the loop will continue forever. For example, if we started the above example at x = -2. The break statement is particularly important for while loops, but can also be used in for loops. However, for loops have virtually no risk of running indefinitely.

colors <- c("red","green","blue","yellow")
for (x in colors) {
  if (x == "blue"){
       break 
  }
  print(x)
}
## [1] "red"
## [1] "green"

On Your Own

While it may not be ideal, one way to “fix” a difficult while loop is to throw a break in there. Use a break to stop the following loop from storing Fibonacci numbers greater than 200.

fibs <- c(0, 1)
itr <- 2

while(fibs[itr] < 200){
  itr <- itr+1
  fibs <- append(fibs, fibs[itr-1]+fibs[itr-2])
}
fibs
##  [1]   0   1   1   2   3   5   8  13  21  34  55  89 144 233

Nested Loops

Loops in loops in loops

for(i in 4:6){
  for(j in 1:3){
    statement = paste("i=", i, ", j=", j)
    print(statement)
  }
}
## [1] "i= 4 , j= 1"
## [1] "i= 4 , j= 2"
## [1] "i= 4 , j= 3"
## [1] "i= 5 , j= 1"
## [1] "i= 5 , j= 2"
## [1] "i= 5 , j= 3"
## [1] "i= 6 , j= 1"
## [1] "i= 6 , j= 2"
## [1] "i= 6 , j= 3"

These are especially good for iterating through matrices

mymat <- matrix(nrow=5, ncol=5)
mymat
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   NA   NA   NA   NA   NA
## [2,]   NA   NA   NA   NA   NA
## [3,]   NA   NA   NA   NA   NA
## [4,]   NA   NA   NA   NA   NA
## [5,]   NA   NA   NA   NA   NA
for(i in 1:5){
  for(j in 1:5){
    mymat[i,j] <- i*j
  }
}
mymat
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    3    4    5
## [2,]    2    4    6    8   10
## [3,]    3    6    9   12   15
## [4,]    4    8   12   16   20
## [5,]    5   10   15   20   25