-
Notifications
You must be signed in to change notification settings - Fork 1
/
L5-loops.Rmd
188 lines (140 loc) · 6.14 KB
/
L5-loops.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
---
title: "Loops"
output: html_document
---
```{r setup, echo=FALSE, message=FALSE, warning=FALSE}
rm(list=objects()) # start with a clean workspace
source("knitr_setup.R")
```
> ### Learning Objectives
>
> * Describe what loops are.
> * Understand the differences and different uses of `for` loops and `while` loops.
> * Understand how to use `break` and `next` statements inside loops.
>
> ### Suggested Readings
>
> * [Chapter 21](https://r4ds.had.co.nz/iteration.html) of "R for Data Science", by Garrett Grolemund and Hadley Wickham
> * [Chapters 11](https://rstudio-education.github.io/hopr/loops.html) of "Hands-On Programming with R", by Garrett Grolemund
---
Similar to conditionals (remember those [if / else statements](L4.1-conditionals.html)?), loops are another kind of "flow control" - that is, code that alters the otherwise linear flow of operations from the top of a script straight through to the end. The idea is simple: a loop is a block of code (i.e., a sequence of commands) that R will execute over and over again until some *termination criterion* is met.
The main two types of loops are `for` and `while` loops.
# The `for` loop
Use `for` loops when there is a known number of iterations. The basic format of a `for` loop goes like this:
```
for (VALUE in SEQUENCE) {
STATEMENT1
STATEMENT2
ETC
}
```
In a `for` loop, R runs a fixed number of iterations determined by the `SEQUENCE` statement, which is a sequence of values. In each iteration, the variable `VALUE` will take the next value in `SEQUENCE`. Once we've exhausted all of the values in `SEQUENCE`, the loop terminates and the flow of the program continues down the script. This schematic illustrates the idea:
<center>
![](images/loop_for.png){ width=350 }
</center>
## Looping over numbers
It is common to use a sequence of integers for the values in `SEQUENCE`. The simplest way to do this is to use the `:` operator. For example, the code `1:10` creates the integers 1 through 10. The following `for` loop uses this sequence to print out each integer in the sequence:
```{r}
# Print the numbers from 1 to 10
for (i in 1:10) {
print(i)
}
```
You can also use the `seq()` function to generate a specific sequence of numbers over which to iterate. This can be useful if you want to control the step size (in the example below, it's 2):
```{r}
# Print the numbers from 1 to 10 with a step size of 2
for (i in seq(1, 10, by=2)) {
print(i)
}
```
## Looping over other things
R will loop over any sequence you create. For example, you can loop over a vector of characters (The `c()` function creates a "vector"...we'll get to those [next lesson](L6-vectors.html)):
```{r}
x <- c('If', 'you', 'want', 'to', 'view', 'paradise,', 'simply', 'look',
'around', 'and', 'view', 'it.')
for (i in x) {
print(i)
}
```
You can also loop over logical values. The following loop will print out the value when it is `TRUE`:
```{r}
x <- c(TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE)
for (i in x) {
if (i == TRUE) {
print(i)
}
}
```
## Nested `for` loops
You can have loops inside loops! This is useful when working on things that have more than one dimension. For example, let's print out a 5 x 5 rectangle out of asterisks (`*`) by looping over rows and columns:
```{r}
n <- 5
for (row in seq(n)) {
for (col in seq(n)) {
cat("*")
}
cat('\n') # Print a new line
}
```
This will come in handy when working with 2-dimensional objects like [data frames](L10-da1-data-frames.html).
---
# The `while` loop
> A friend calls her programmer roommate and says, "while you're out, buy some milk"...her roommate never returned home.
>
> ![](images/laugh_emoji.png){ width=100 }
Use while loops when there is an indeterminate number of iterations. The basic format of the loop looks like this:
```
while (CONDITION) {
STATEMENT1
STATEMENT2
ETC
}
```
The code corresponding to `CONDITION` needs to produce a logical value, either `TRUE` or `FALSE`. Whenever R encounters a while statement, it checks to see if the condition is `TRUE`. If it is, R goes on to execute all of the commands inside the curly brackets. R will then continue to repeat this process until the condition is `FALSE`. Once that happens, R jumps to the bottom of the loop (i.e., to the `}` character), and then continues on with whatever commands appear next in the script. This schematic illustrates the idea:
<center>
![](images/loop_while.png){ width=350 }
</center>
**Example**:
The following function prints each power of 2 up to an upper limit:
```{r}
powersOfTwo <- function(upperLimit) {
n = 1
while (n < upperLimit) {
print(n)
n = 2*n
}
}
```
```{r}
powersOfTwo(5)
powersOfTwo(100)
```
---
# The break and next statements
## break
You can force a loop to stop by inserting the `break` statement in the loop. In a nested loop, the `break` statement exits from the innermost loop that is being evaluated. Here's an example:
```{r}
for (val in 1:5) {
if (val == 3) {
break
}
print(val)
}
```
In this example, we iterate over the consecutive numbers from 1 to 5. Inside the for loop we have used a if condition to break if the current value is equal to 3. As we can see from the output, the loop terminates when it encounters the break statement.
## next
A `next` statement is useful when we want to skip the current iteration of a loop without terminating it. On encountering `next`, R will jump to the end of the loop and start the next iteration. Here's an example:
```{r}
for (val in 1:5) {
if (val == 3) {
next
}
print(val)
}
```
In the above example, we use the `next` statement inside an `if` statement to check if the value is equal to 3. If the value is equal to 3, the current evaluation stops (i.e. the value is not printed) and the loop continues with the next iteration.
---
**Page sources**:
Some content on this page has been modified from other courses, including:
- CMU [15-112: Fundamentals of Programming](http://www.kosbie.net/cmu/spring-17/15-112/), by [David Kosbie](http://www.kosbie.net/cmu/) & [Kelly Rivers](https://hcii.cmu.edu/people/kelly-rivers)
- Danielle Navarro's website ["R for Psychological Science"](https://psyr.org/index.html)