1.6 Flow control

As we have seen when defining our first scalars or vectors (in Sections 1.3 and 1.4), it matters in which order we define objects. For instance, the following example first defines x as a (numeric) scalar 1, but then re-assigns x to a vector (of type integer) 1:10, before re-assigning x to a scalar (of type character) “oops”:

# Assigning x:
x <- 1
typeof(x)
#> [1] "double"

# Re-assigning x:
x <- 1:10
typeof(x)
#> [1] "integer"

# Re-assigning x:
x <- "oops"
typeof(x)
#> [1] "character"

Although this example may seem trivial, it illustrates 2 important points:

  1. R executes code sequentially: The order in which code statements and assignments are evaluated matters.

  2. Whenever changing an object by re-assigning it, any old content of it (and its type) is lost.

At first, this dependence on evaluation order and the “forgetfulness” of R may seem like a nuisance. However, both features actually have their benefits when programming algorithms that require distinctions between cases or repeated executions of code. We will discuss such cases in our introduction to Programming (see Chapters 11 and 12). But as it is likely that you will encounter examples of if-then statements or loops before getting to these chapters, we briefly mention 2 major ways in which we can control the flow of information here.

1.6.1 If-then

The basic structure of a conditional test in R is the following:

if (<TEST>) {<THEN>}
if (<TEST>) {<THEN>} else {<ELSE>}

Notice 2 different types of parentheses: Whereas the <TEST> is enclosed in round parentheses (), the <THEN> and <ELSE> parts are enclosed in curly brackets {}.

Example

if (TRUE)  { x <- 10 }
x
#> [1] 10
if (FALSE) { x <- 11 } else { x <- 12 } 
x
#> [1] 12

Practice

  • Predict the final outcome of evaluating y in the following code and then evaluate it to check your prediction:
y <- 11:22
if (length(y) > 11)  { x <- 30 } else { x <- 31 } 
y <- "wow"
if (x < 31) { y <- x } else { y <- "!" }
y

We will learn more about if-then statements in our chapter on Functions (Chapter 11).

1.6.2 Loops

The basic structure of a for loop in R is the following:

for (i in <LOOP_RANGE>) {
  
  <LOOP-BODY>

}

The code in <LOOP-BODY> is executed repeatedly — as often as indicated in <LOOP_RANGE>. The variable i serves as a counter that indicates the current iteration of the loop.

Example

for (i in 1:10) {
  
  print(i)

}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5
#> [1] 6
#> [1] 7
#> [1] 8
#> [1] 9
#> [1] 10

Practice

  • Predict the effects of the following loops and then evaluate them to check your prediction:
for (i in 4:9) {
  
  print(i^2)

}
for (i in 10:99) {
  
  if (sqrt(i) %% 1 == 0) { print(i) }

}

We will learn more about loops in our chapter on Iteration (Chapter 12).