Loops let us tell R to run a series of commands multiple times. R has two types of loops: while
and for
.
A while
loop performs a task until a particular condition is no longer met.
while( condition ){
this
code
chunk
will
not
run
}
condition
is any logical statement.
TRUE
, the loop will continue to repeat.FALSE
, the loop will finish its current iteration and stop.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.
Use a while
loop to print out 5, then 4, then 3, then 2, then 1.
x <- 5
# while loop
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.
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 ##
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"
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
We can use a next
command in loops in order to skip executing a command.
for(i in 1:10){
i <- i^2
if(i <5){
next
}
print(i)
}
## [1] 9
## [1] 16
## [1] 25
## [1] 36
## [1] 49
## [1] 64
## [1] 81
## [1] 100
The code runs until it hits the next
statement, at which point it moves directly to the next iteration of the loop. In this case, it will not print when i=1 or when i=4, but it will continue the loop so that the rest of the iterations will print their results.
Use a next
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
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