Chapter 4 Loops in R

  • Loops are typically used when we want to repeat some type of calculation many times.

  • The two types of loops in R are the for loop and the while loop.

  • For loops:

    • Typically used when we know exactly how many times we need to repeat a calculation.
  • While loops:

    • Typically used when we only want to repeat some calculation until some condition is satisfied.

4.1 For Loops

  • The general form of a for loop in R is
for (x in vec_name) {
    perform a calculation (often involving x)
}
  • The for loop will execute the code underneath the for statement \(T\) times where \(T\) is the length of the vector vec_name.

  • Each time the code is executed, x will be set to one element in vec_name.

4.1.1 Example 1: printing the first 5 integers

  • As an example, let’s write a for loop that prints the first 5 positive integers:
for (k in 1:5) {
    print(k)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
  • Each time you go inside the loop, the variable k takes the next value in the vector 1:5 and is printed to the screen.

4.1.2 Example 2: computing 10 factorial

  • As another example, let’s use a for loop to compute the product \[\begin{equation} 10! = 1 \times 2 \times 3 \times ... \times 9 \times 10 \nonumber \end{equation}\]
prod_ten <- 1   # start from 1

for(x in 2:10)  {  # iterate x from 1 thru 10
   prod_ten <- prod_ten*x   # multiply each value
}
print(prod_ten)     # print the product of first 10 integers
## [1] 3628800

4.1.3 Example 3: a non-numeric looping variable

  • The looping variable does not need to be numeric.

  • Here is an example where the looping variable has character type.

fruits <- c("apple","orange","grape")   # character vector
for(fruit in fruits)  {  # iterate each element
   print(fruit)   
}
## [1] "apple"
## [1] "orange"
## [1] "grape"

4.1.4 Example 4: first Fibonacci numbers

  • The Fibonacci sequence is a sequence of numbers \(x_{1}, x_{2}, x_{3}, ...\) defined by the relationship: \[\begin{equation} x_{k} = x_{k-1} + x_{k-2} \nonumber \end{equation}\]

  • The first two numbers in the Fibonacci sequence are \(x_{1} = 0\) and \(x_{2} = 1\).

  • We want to write R code that stores the first \(n\) Fibonacci numbers in a vector.

  • To do this, it is more efficient to first create a vector of zeros and then fill in the Fibonacci numbers into this vector.

    • This is done by first assigning x the vector rep(0, n)
## R code for computing first 12 Fibonacci numbers
x <- rep(0, 12)  # First initialize a vector of size 12
x[1] <- 0
x[2] <- 1
for(k in 3:12) {
    ## start at index 3 since first 2 elements are filled in
    x[k] <- x[k-1] + x[k-2]
}
x
##  [1]  0  1  1  2  3  5  8 13 21 34 55 89

  • You could create a vector of the first \(n\) Fibonacci numbers by “appending” an extra number to the vector x each time we go in the loop.

  • This is usually much slower than first initializing a vector as was done on the previous slide.

## R code for computing first 12 Fibonacci numbers
x <- c(0, 1)
for(k in 3:12) {
    x <- c(x, x[k-1] + x[k-2])
}
x
##  [1]  0  1  1  2  3  5  8 13 21 34 55 89

4.1.5 Nested for loops

  • You can have a for loop within another for loop.
    • These are usually referred to as nested for loops.
for (i in 1:3) {   # i iterates over 1,2,3
  for (j in 1:i) { # j iterates over 1 to i
      print(c(i,j))     
  }
}
## [1] 1 1
## [1] 2 1
## [1] 2 2
## [1] 3 1
## [1] 3 2
## [1] 3 3

4.1.6 break and next: Exiting for loops and skipping iterations

  • You can use the break statement to terminate a loop.
    • The for loop will be stopped whenever the statement break is encountered.
  • As an example of this, let’s write a loop that should run for 5 iterations, but is terminated after during it’s 3rd iteration.
for(k in 1:5) {
    print(k)
    if(k >= 3) {
       break   ## loop will stop when break is run
    }
}
## [1] 1
## [1] 2
## [1] 3
  • Note that if we move the print statement after break in the above example, then only 1 and 2 will be printed to the screen.
for(k in 1:5) {
    if(k >= 3) {
       break   ## loop will stop when break is run
    }
    print(k)
}
## [1] 1
## [1] 2

  • break statements can be used within nested loops.

  • If using a break statement in the inner loop of a nested loop, only the inner loop will be terminated when break is run.

for (i in 1:3) {   # i iterates over 1,2,3
  for (j in 1:3) { # j iterates over 1,2,3
     print(c(i,j))
     if (j == i) {  ## if j and i are the same
        break        ## finish the inner loop 
     }
  }
}
## [1] 1 1
## [1] 2 1
## [1] 2 2
## [1] 3 1
## [1] 3 2
## [1] 3 3

  • The next statement is used to skip the remainder of a current iteration.

  • When the next statement is encountered, you will go directly to the next iteration and not execute whatever was remaining inside the body of the for loop.

  • Let’s try an example where we have 5 iterations setup, but we use a next statement within the 3rd iteration

for(k in 1:5) {
   if(k == 3) {
       next
   }
   print(k)  # this will not print when k==3 
}
## [1] 1
## [1] 2
## [1] 4
## [1] 5

  • next can also be used within a nested loop.

  • If used in an inner loop, the next statement will skip the remainder of the current inner loop iteration and go to the next inner loop iteration.

for (i in 1:3) {   # i iterates over 1,2,3
  for (j in 1:3) { # j iterates over 1,2,3
    if (j == i) {   ## if j equals i 
       next         ## go to next iteration
    }               ## of inner loop
    print(c(i,j))
  }
}
## [1] 1 2
## [1] 1 3
## [1] 2 1
## [1] 2 3
## [1] 3 1
## [1] 3 2

4.2 While Loops

  • For loops execute a piece of code a set number of times.

  • While loops keep executing the piece of code as long as a certain condition is TRUE.

  • The general form of a while loop in R is

while(condition) {
    code chunk
    then, usually update something related to condition
}
  • condition is a logical expression.

  • The code_chunk inside the loop is repeated until the condition becomes FALSE in which case the loop stops.


  • Basic example of while loop:
prod <- 1   # start from 1
while(prod < 100)  {  # repeat the block until condition is true
  print(prod)          # print the value of prod
  prod <- prod * 2     # and double the value
}
## [1] 1
## [1] 2
## [1] 4
## [1] 8
## [1] 16
## [1] 32
## [1] 64

4.2.1 Example 1: a “first which” function

  • We can use a while loop to find the first occurrence of a number in a vector.

  • Specifically, for an input vector x and input number num, we want to find the first index k such that x[k] == num

  • This function will also return NA if no match is found.

first_while <- function(x, num) {
  index.count <- 0
  match.not.found <- TRUE
  while(match.not.found && index.count < length(x)) {
    # want to keep loop running while match is not found
    # and the index is less than the length of x
    index.count <- index.count + 1 
    match.not.found <- !(x[index.count] == num)
  }
  if(match.not.found) {
    index.count <- NA
  }
  return(index.count)
}
  • Let’s try running first_while on a few examples:
first_while(1:5, 3)
## [1] 3
first_while(1:5, 6)
## [1] NA
first_while(1:5, 5)
## [1] 5
first_while(rep(1:3, each=4), 2)
## [1] 5

4.3 Exercises

  1. What will the value of the variable count be after running the following code:
x <- rep(c(-1,1), each=3)
y <- x > 0
x <- c(3, 3, 3, 5, 5)
count <- 0
for(k in 1:4) {
   count <- count + 1
   if( x[k] != x[k+1]) {
        break
   } 
}