After working through this handout, you should:
* Know how to use while loops in R
While loops have a different structure compared to for loops. A while loop consists of a condition and a block of code. The loop continues to execute as long as the condition is TRUE. When the condition becomes FALSE, the loop stops. While loops are more versatile for situations where you don’t know the exact number of iterations in advance, as the loop continues until the condition becomes false. For loops are better when you know the exact number of iterations. In a for loop, you typically initialize a counter variable and specify how it should be updated with each iteration. In a while loop, these initialization and update actions are handled manually, outside of the loop structure.
Let’s look at a pair of examples, each calculating the sum of the integers from 1 to n. This can be done with a for loop or a while loop.
#Compute the sum of integers from 1 to n using a for loop
n <- 10
sum <- 0
for (i in 1:n) {
sum <- sum + i
}
sum
## [1] 55
# Same thing using a while loop
n <- 10
sum <- 0
i <- 1
while (i <= n) {
sum <- sum + i
i <- i + 1
}
sum
## [1] 55
In the above example, a for loop is probably more sensible than a while loop. Next, we will consider an example where a while loop is necessary or at lest notably more sensible. In this example I will first generate a long list of random numbers. I will then use a while loop to calculate the sum of the first 10 negative numbers in the list.
## generate some numbers
x <- rnorm(5000, mean = 3, sd = 2)
sum <- 0
cnt <- 0
i <- 1
while (cnt < 10) {
## keep going till I have found and summed 10 negative numbers
if (x[i] < 0) {
sum <- sum + x[i]
cnt <- cnt + 1
}
i <- i + 1
}
cat("The sum of the", cnt, "random numbers was", sum)
## The sum of the 10 random numbers was -7.499326
cat("This took", i, "iterations")
## This took 210 iterations
Another great example where you’d want a while loop is when performing an optimization procedure, like our golden search example.
goldenSearch<-function(a=0,b=1,y=NA,N=NA,tol=0.001){
#Define golden ratio
phi<-(1+sqrt(5))/2
err<-b-a
#Compute values of of x1 and x2
x1<-b-(b-a)/phi
x2<-a+(b-a)/phi
#Test of error > tolerance if so
#Enter while loop
while(err > tol){
#Compute -log likelihoods
lx1<- -log(dbinom(y,size=N,x1))
lx2<- -log(dbinom(y,size=N,x2))
if(lx1 > lx2){ ## min to right of x1
a<-x1
x1<-b-(b-a)/phi
x2<-a+(b-a)/phi
} else{ #Min to left
b<-x2
x1<-b-(b-a)/phi
x2<-a+(b-a)/phi
}
#New error
err<-b-a
}
#Return lower and upper bounds and mean
return(c(a,b,(a+b)/2))
}
A note of caution: it is easy to write a while loop that runs forever. Make sure that the exit conditions will eventually be met, otherwise you might have to stop the code from exiting manually.
\[ \] \[ \] \[ \] \[ \]