Flow control
December 20 2022
flow.RmdComparisons – testing for equality and difference
These tests are essential for while loops, and other
forms of flow control such as if statements. They allow us
to test whether something is true, and change what lines of code are run
depending on the outcome. There are the basic tests:
-
a == b: isaequal tob? (TRUEif this is true,FALSEif this is false) -
a > b: isagreater thanb? -
a < b: isaless thanb? -
a >= b: isagreater than or equal tob? -
a <= b: isaless than or equal tob? -
a != b: isadifferent fromb?
There are then three basic ways of changing or combining the above:
-
(a < b) || (c == d): is eitheraless thanborcequal tod? -
(a < b) && (c == d): is bothaless thanbandcequal tod? -
!((a < b) && (c == d)): is the above notTRUE?TRUEif the above wasFALSEand vice versa
Remember to use (lots of!) brackets to ensure you are combining
things in the right order. These tests can be used in the
while loops above to determine whether to continue through
the next iteration of the loop, and in the if statements
below, to determine what to do next.
We introduced these concepts in Lecture 7a. Comparisons are also covered in passing in R4DS, and by R Coder in a bit more depth here.
if (something) and
if (something) { ... } else { ... } statements
The if command allow us to perform a test, and if the
result is TRUE run a block of R code (in curly brackets
{ ... }). Optionally, if the test is FALSE, a
different block of code can be run instead. This allows us to do a
variety of things. To give a very simple example:
if (2 > 1) {
print("Maths works!")
}
#> [1] "Maths works!"This prints "Maths works!" because the test is
TRUE, so the code block that follows is run. Whereas:
This prints "Less than 5." because the test was false,
so R continues to the code block after the else statement.
If there is no else statement, then no code is run, so:
if (2 >= 5) {
print("At least 5.")
}does nothing. We use if and if ... else
statements throughout the helper functions and the example code you’ve
been provided with. For instance:
library(codetools)
library(RPiR)
if (length(findGlobals(plot_simple, merge = FALSE)$variables) != 0) {
stop("Function plot_simple() may not use global variable(s): ",
findGlobals(plot_simple, merge = FALSE)$variables)
}This checks whether
length(findGlobals(plot_simple, merge=FALSE)$variables) is
non-zero, which is to say whether the variables element of
what is returned by findGlobals(plot_simple, merge = FALSE)
is not of length zero, i.e. whether there are any global
variables in the function plot_simple. If there are, then
the contents of the curly brackets are run, stop(...) is
called, and the code stops running. In fact, plot_simple
has no global variables, so the code block is not run.
In Practical 3-4 we provide a second example of an if
statement, used to control code execution:
if (first.graph) {
plot_populations(final.populations,
new.graph = TRUE,
col = c(susceptibles = "green", infecteds = "red"))
first.graph <- FALSE
} else {
plot_populations(final.populations,
new.graph = FALSE,
col = c(susceptibles = "green", infecteds = "red"))
}This code tests whether the variable first.graph is
TRUE. If it is, the following code block is run, and it
plots a graph into a new graphics window and sets
first.graph to FALSE. In the practical, this
code is run inside a loop, and the next (and every subsequent) time it
runs, first.graph is already FALSE so the code
block following the else statement is run, and a plot is
superimposed on the existing graphics window.
We introduced these concepts in Lecture 5b. R Coder covers the basics
of if statements here. R4DS seems to consider
them too simple, but ironically they have a chapter in Advanced
R; however, this contains a lot of advanced topics in flow control
that are well beyond the scope of this course.