Control Flow

Choices and Iteration

Last Time

  1. A list is a non-atomic vector: types can be mixed.
  2. [] subsets a list and returns a list.
  3. [[ ]] and $ return the object inside the list.
  4. Lists can nest, so subsetting can be chained.
  5. $ allows subsetting by name.

Key Ideas for Today

  1. Use comparison operators to compare two values.
  2. if-then runs code only when a condition is TRUE.
  3. if-else chooses between two blocks of code based on condition.
  4. A for loop repeats code for each element of a vector.
  5. ifelse() is a vectorized if-else.

Comparisons

Comparison operators

Comparison Operator

A symbol that compares two values and returns a logical: TRUE if the comparison holds, FALSE otherwise.

<
>
<=
>=

==
!=
%in%

Examples

c("apple", "orange", "apple", "kiwi") == "apple"
[1]  TRUE FALSE  TRUE FALSE
"apple" == c("apple", "orange", "apple", "kiwi")
[1]  TRUE FALSE  TRUE FALSE
"apple" %in% c("apple", "orange", "apple", "kiwi")
[1] TRUE
c("apple", "orange", "apple", "kiwi") %in% "apple"
[1]  TRUE FALSE  TRUE FALSE

Examples

c("apple", "kiwi") %in% c("apple", "orange", "apple", "kiwi")
[1] TRUE TRUE
c("apple", "orange", "apple", "kiwi") %in% c("apple", "kiwi")
[1]  TRUE FALSE  TRUE  TRUE
  • Don’t forget logicals are 1s and 0s.

Examples

m <- matrix(1:4, nrow = 2)
m
     [,1] [,2]
[1,]    1    3
[2,]    2    4
m > 2
      [,1] [,2]
[1,] FALSE TRUE
[2,] FALSE TRUE
sum(m > 2)
[1] 2
sum(m[m > 2])
[1] 7

Choices

Getting to Campus

If my bike is working
     then I ride my bike to campus.

If my bike is not working and I have enough time
     then I ride the bus to campus.

If my bike is not working and I don’t have enough time
     then I take a cab.

A random condition in R

sample(x = -10:10, size = 1)
[1] -4

sample() will randomly sample 1 element from the vector x.

if-then Statement

Executes a block of code only when a condition evaluates to TRUE; otherwise the block is skipped.

x <- sample(x = -10:10, size = 1)

if (x > 0) {
  print("x is positive :)")
}

if-else Statement

Executes one block of code if a condition is met and a different block if it is not — exactly one branch always runs.

x <- sample(x = -10:10, size = 1)

if (x > 0) {
  print("x is positive :)")
} else {
  print("x is negative :(")
}

Nested ifs

x <- sample(x = -10:10, size = 1)

if (x > 0) {
  print("x is positive :)")
} else if (x < 0) {
  print("x is negative :(")
} else {
  print("x is zero :|")
}

Getting to Campus

If my bike is working
     then I ride my bike to campus.

If my bike is not working and I have enough time
     then I ride the bus to campus.

If my bike is not working and I don’t have enough time
     then I take a cab.

Your Turn

Using the R objects bike_working and enough_time, both logical vectors of length 1, write this decision tree in R using nested if-then statements and print().

02:30

if (bike_working) {
  print("ride bike")
} else if (enough_time) {
  print("ride bus")
} else {
  print("call cab")
}

Iteration

For Loop

Repeats a block of code once for each element of a vector, with a loop variable taking each value in turn.

for (item in vector) {
    perform_action
}

Example

Goal: Build the first 10 elements of the Fibonacci Sequence.

n <- 10
fib <- rep(1, n) # pre-allocate a double vector

for (i in 3:n) {
  fib[i] <- fib[i - 1] + fib[i - 2]
}

fib
 [1]  1  1  2  3  5  8 13 21 34 55

Iterated Choices

What if x has multiple elements?

x <- rnorm(3)
x
[1] -0.2155415 -1.0925180  0.7512622




      if (x > 0) {
        print("x is positive :)")
      }

Option 1

for (i in 1:length(x)) {
  if (x[i] > 0) {
    print("x is positive :)")
  }
}
[1] "x is positive :)"

Option 2

for (i in 1:length(x)) {
  if (x[i] > 0) {
    print(paste("element", i, "is positive :)"))
  }
}
[1] "element 3 is positive :)"

Option 3

for (x_elem in x) {
  if (x_elem > 0) {
    print(paste(x_elem, "is positive :)"))
  }
}
[1] "0.751262154884219 is positive :)"

ifelse()

ifelse()

A vectorized if-else: applies a condition to every element of a vector at once, without an explicit loop.

x < 0 
[1]  TRUE  TRUE FALSE
ifelse(test = x < 0, yes = "is positive :)", no = "is negative :(")
[1] "is positive :)" "is positive :)" "is negative :("

Guess the metaphor

An if-then statement is like a fork in the road: the computer will take one of two paths based on a condition.

Key Ideas for Today

  1. Use comparison operators to compare two values.
  2. if-then runs code only when a condition is TRUE.
  3. if-else chooses between two blocks of code based on condition.
  4. A for loop repeats code for each element of a vector.
  5. ifelse() is a vectorized if-else.

For Next Time

  1. Practice with Control Flow
  2. Finish Project and prepare for Project Studio 1!