+ - 0:00:00
Notes for current slide
Notes for next slide

Advanced R

Chapter 5: Control flow

Erick Knackstedt

@Eknackstedt

2020-08-27

1 / 39

Outline

  • Choices with if(), ifelse(), switch(), and case_when()
2 / 39

Outline

  • Choices with if(), ifelse(), switch(), and case_when()

  • Looping with for, while, and repeat

3 / 39

Outline

  • Choices with if(), ifelse(), switch(), and case_when()

  • Looping with for, while, and repeat

  • Exercises

4 / 39

Choices

What is the basic form of an if() statement?

5 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action
6 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

7 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

  • A statement that evaluates to a single TRUE or FALSE condition
8 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

  • A statement that evaluates to a single TRUE or FALSE condition

For the action?

9 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

  • A statement that evaluates to a single TRUE or FALSE condition

For the action?

  • An action or a value. For FALSE, same as TRUE but can also be omitted
10 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

  • A statement that evaluates to a single TRUE or FALSE condition

For the action?

  • An action or a value. For FALSE, same as TRUE but can also be omitted

What does an if() statement return?

11 / 39

Choices

What is the basic form of an if() statement?

if (condition) true_action
if (condition) true_action else false_action

What are valid inputs for the condition?

  • A statement that evaluates to a single TRUE or FALSE condition

For the action?

  • An action or a value. For FALSE, same as TRUE but can also be omitted

What does an if() statement return?

  • A value on TRUE
  • A value or NA on FALSE
12 / 39

Choices cont.

What is the difference between if() and ifelse()?

13 / 39

Choices cont.

What is the difference between if() and ifelse()?

  • ifelse() is vectorised
  • if() only accepts a single TRUE or FALSE. ifelse() can iterate a conditional check and evaluate the expression for each element being iterated on
14 / 39

Choices cont.

What is the difference between if() and ifelse()?

  • ifelse() is vectorised
  • if() only accepts a single TRUE or FALSE. ifelse() can iterate a conditional check and evaluate the expression for each element being iterated on

Is there another alternative to ifelse()?

15 / 39

Choices cont.

What is the difference between if() and ifelse()?

  • ifelse() is vectorised
  • if() only accepts a single TRUE or FALSE. ifelse() can iterate a conditional check and evaluate the expression for each element being iterated on

Is there another alternative to ifelse()?

  • case_when() is vectorised and allows multiple condition/value pairs
16 / 39

Choices cont.

What is the difference between if() and ifelse()?

  • ifelse() is vectorised
  • if() only accepts a single TRUE or FALSE. ifelse() can iterate a conditional check and evaluate the expression for each element being iterated on

Is there another alternative to ifelse()?

  • case_when() is vectorised and allows multiple condition/value pairs

Ok, so if() lets me create logical branches when the condition evaluates to FALSE. Is there a way I can get around nesting if statements?

17 / 39

Choices cont.

What is the difference between if() and ifelse()?

  • ifelse() is vectorised
  • if() only accepts a single TRUE or FALSE. ifelse() can iterate a conditional check and evaluate the expression for each element being iterated on

Is there another alternative to ifelse()?

  • case_when() is vectorised and allows multiple condition/value pairs

Ok, so if() lets me create logical branches when the condition evaluates to FALSE. Is there a way I can get around nesting if statements?

  • There is! switch()
  • switch() seems to take a vector of values to use in the conditional statement, and then a list of value/action pairs to describe the different actions to take based on evaluation.
18 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

19 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

  • While iteration is built into a lot of functions, often times you need to leverage iteration manually. Loops are the tools to achieve this.
for (item in vector) perform_action
  • Within parenthesis you name an element from a vector of values.
  • In the action you can use the element value in the action or ignore it
20 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

  • While iteration is built into a lot of functions, often times you need to leverage iteration manually. Loops are the tools to achieve this.
for (item in vector) perform_action
  • Within parenthesis you name an element from a vector of values.
  • In the action you can use the element value in the action or ignore it

What happens to the value assigned to the item?

21 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

  • While iteration is built into a lot of functions, often times you need to leverage iteration manually. Loops are the tools to achieve this.
for (item in vector) perform_action
  • Within parenthesis you name an element from a vector of values.
  • In the action you can use the element value in the action or ignore it

What happens to the value assigned to the item?

  • The item <- value assignment exists in the execution environment, until overwritten or slotted away.
  • This implies that if you are assigning values you should pre-allocate a memory container. Be specific about the value type.
22 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

  • While iteration is built into a lot of functions, often times you need to leverage iteration manually. Loops are the tools to achieve this.
for (item in vector) perform_action
  • Within parenthesis you name an element from a vector of values.
  • In the action you can use the element value in the action or ignore it

What happens to the value assigned to the item?

  • The item <- value assignment exists in the execution environment, until overwritten or slotted away.
  • This implies that if you are assigning values you should pre-allocate a memory container. Be specific about the value type.

When should I create the container, and where?

23 / 39

Loops

I really don't want to repeat this task over and over again. What can I do?

  • While iteration is built into a lot of functions, often times you need to leverage iteration manually. Loops are the tools to achieve this.
for (item in vector) perform_action
  • Within parenthesis you name an element from a vector of values.
  • In the action you can use the element value in the action or ignore it

What happens to the value assigned to the item?

  • The item <- value assignment exists in the execution environment, until overwritten or slotted away.
  • This implies that if you are assigning values you should pre-allocate a memory container. Be specific about the value type.

When should I create the container, and where?

  • Set up the container before you run the loop
  • Set the container up in the execution environment (if you are running the loop in function, set up the container in the function)
24 / 39

Loops cont.

For loops use the index to determine the number of iterations. What if I don't know the number of iterations up front?

25 / 39

Loops cont.

For loops use the index to determine the number of iterations. What if I don't know the number of iterations up front?

  • This is where while and repeat come in handy
  • With a while loop you define the number of iterations conditionally, using the logic covered in the section on Choice
  • With a repeat loop the process iterates until it encounters break
26 / 39

Loops cont.

For loops use the index to determine the number of iterations. What if I don't know the number of iterations up front?

  • This is where while and repeat come in handy
  • With a while loop you define the number of iterations conditionally, using the logic covered in the section on Choice
  • With a repeat loop the process iterates until it encounters break

I get the purpose of a while loop. But what about a repeat loop?

27 / 39

Loops cont.

For loops use the index to determine the number of iterations. What if I don't know the number of iterations up front?

  • This is where while and repeat come in handy
  • With a while loop you define the number of iterations conditionally, using the logic covered in the section on Choice
  • With a repeat loop the process iterates until it encounters break

I get the purpose of a while loop. But what about a repeat loop?

  • I'm with ya, I don't get it either. Anybody?
28 / 39

Loops cont.

For loops use the index to determine the number of iterations. What if I don't know the number of iterations up front?

  • This is where while and repeat come in handy
  • With a while loop you define the number of iterations conditionally, using the logic covered in the section on Choice
  • With a repeat loop the process iterates until it encounters break

I get the purpose of a while loop. But what about a repeat loop?

  • I'm with ya, I don't get it either. Anybody?

Apparently it is powerful though. To quote from the book:

You can rewrite any for loop to use while instead, and you can rewrite any while loop to use repeat, but the converses are not true. That means while is more flexible than for, and repeat is more flexible than while. It’s good practice, however, to use the least-flexible solution to a problem, so you should use for wherever possible.

29 / 39

Exercises 5.2.4

What type of vector does each of the following calls to ifelse() return?

ifelse(TRUE, 1, "no")
ifelse(FALSE, 1, "no")
ifelse(NA, 1, "no")
30 / 39

Exercises 5.2.4

What type of vector does each of the following calls to ifelse() return?

ifelse(TRUE, 1, "no")
ifelse(FALSE, 1, "no")
ifelse(NA, 1, "no")

The "choice" is evaluated to true, false, and unknown, respectively. The return values are mixed between numeric and character values, while unknown is returned for an unknown evaluation.

31 / 39

Exercises 5.2.4 cont.

Why does the following code work?

x <- 1:10
if (length(x)) "not empty" else "empty"
#> [1] "not empty"
x <- numeric()
if (length(x)) "not empty" else "empty"
#> [1] "empty"
32 / 39

Exercises 5.2.4 cont.

Why does the following code work?

x <- 1:10
if (length(x)) "not empty" else "empty"
#> [1] "not empty"
x <- numeric()
if (length(x)) "not empty" else "empty"
#> [1] "empty"

0 and 1 represent FALSE and TRUE. The length function in the first case returns a positive integer, while in the second case return a 0. 0 is interpreted as FALSE, while 1+ is interpreted as TRUE.

33 / 39

Exercises 5.3.3

Why does this code succeed without errors or warnings?

x <- numeric()
out <- vector("list", length(x))
for (i in 1:length(x)) {
out[i] <- x[i] ^ 2
}
out
34 / 39

Exercises 5.3.3

Why does this code succeed without errors or warnings?

x <- numeric()
out <- vector("list", length(x))
for (i in 1:length(x)) {
out[i] <- x[i] ^ 2
}
out

Iteration on a zero length vector returns an unknown value.

35 / 39

Exercises 5.3.3 cont.

When the following code is evaluated, what can you say about the vector being iterated?

x <- c(1, 2, 3)
xs <- c(1, 2, 3)
for (x in xs) {
xs <- c(xs, x * 2)
}
xs
36 / 39

Exercises 5.3.3 cont.

When the following code is evaluated, what can you say about the vector being iterated?

x <- c(1, 2, 3)
xs <- c(1, 2, 3)
for (x in xs) {
xs <- c(xs, x * 2)
}
xs

This is replication a vertorized operation using a for loop. It concatenates the string, and each element * 2.

37 / 39

Exercises 5.3.3 cont.

What does the following code tell you about when the index is updated?

for (i in 1:3) {
i <- i * 2
print(i)
}
#> [1] 2
#> [1] 4
#> [1] 6
38 / 39

Exercises 5.3.3 cont.

What does the following code tell you about when the index is updated?

for (i in 1:3) {
i <- i * 2
print(i)
}
#> [1] 2
#> [1] 4
#> [1] 6

This assigns the value to i, multiplies it by 2, and then prints the value assigned to i. It repeats this for each element in the vector. At the end, you see all values printed once, while i points to the last value it was assigned during iteration, 6.

39 / 39

Outline

  • Choices with if(), ifelse(), switch(), and case_when()
2 / 39
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow