Flow control
December 20 2022
flow.Rmd
Comparisons – 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
: isa
equal tob
? (TRUE
if this is true,FALSE
if this is false) -
a > b
: isa
greater thanb
? -
a < b
: isa
less thanb
? -
a >= b
: isa
greater than or equal tob
? -
a <= b
: isa
less than or equal tob
? -
a != b
: isa
different fromb
?
There are then three basic ways of changing or combining the above:
-
(a < b) || (c == d)
: is eithera
less thanb
orc
equal tod
? -
(a < b) && (c == d)
: is botha
less thanb
andc
equal tod
? -
!((a < b) && (c == d))
: is the above notTRUE
?TRUE
if the above wasFALSE
and 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.