Control Flow Structures STAT 133 Gaston Sanchez Department of - - PowerPoint PPT Presentation

control flow structures
SMART_READER_LITE
LIVE PREVIEW

Control Flow Structures STAT 133 Gaston Sanchez Department of - - PowerPoint PPT Presentation

Control Flow Structures STAT 133 Gaston Sanchez Department of Statistics, UCBerkeley gastonsanchez.com github.com/gastonstat/stat133 Course web: gastonsanchez.com/stat133 Expressions 2 Expressions R code is composed of a series of


slide-1
SLIDE 1

Control Flow Structures

STAT 133 Gaston Sanchez

Department of Statistics, UC–Berkeley gastonsanchez.com github.com/gastonstat/stat133 Course web: gastonsanchez.com/stat133

slide-2
SLIDE 2

Expressions

2

slide-3
SLIDE 3

Expressions

R code is composed of a series of expressions

◮ assignment statements ◮ arithmetic expressions ◮ function calls ◮ conditional statements ◮ etc 3

slide-4
SLIDE 4

Simple Expressions

# assignment statement a <- 12345 # arithmetic expression 525 + 34 - 280 # function call median(1:10)

4

slide-5
SLIDE 5

Expressions

One way to separate expressions is with new lines:

a <- 12345 525 + 34 - 280 median(1:10)

5

slide-6
SLIDE 6

Grouping Expressions

Constructs for grouping together expressions

◮ semicolons ◮ curly braces 6

slide-7
SLIDE 7

Separating Expressions

Simple expressions separated with new lines:

a <- 10 b <- 20 d <- 30

7

slide-8
SLIDE 8

Grouping Expressions

Grouping expressions with semicolons:

a <- 10; b <- 20; d <- 30

8

slide-9
SLIDE 9

Grouping Expressions

Grouping expressions with braces:

{ a <- 10 b <- 20 d <- 30 }

9

slide-10
SLIDE 10

Grouping Expressions

Multiple expressions in one line within braces:

{a <- 10; b <- 20; d <- 30}

10

slide-11
SLIDE 11

Brackets and Braces in R

Symbol Use

[ ]

brackets

Objects

( )

parentheses

Functions

{ }

braces

Expressions

11

slide-12
SLIDE 12

Brackets and Braces

# brackets for objects dataset[1:10]

12

slide-13
SLIDE 13

Brackets and Braces

# brackets for objects dataset[1:10] # parentheses for functions some_function(dataset)

12

slide-14
SLIDE 14

Brackets and Braces

# brackets for objects dataset[1:10] # parentheses for functions some_function(dataset) # brackets for expressions { 1 + 1 mean(1:5) tbl <- read.csv('datafile.csv') }

12

slide-15
SLIDE 15

Test yourself

Which is NOT a valid option for indexing data.frames A) Numeric vectors B) Logical vectors C) Missing values D) Empty indices E) Blank spaces

13

slide-16
SLIDE 16

Expressions

◮ A program is a set of instructions ◮ Programs are made up of expressions ◮ R expressions can be simple or compound ◮ Every expression in R has a value 14

slide-17
SLIDE 17

Expressions

# Expressions can be simple statements: 5 + 3 ## [1] 8 # Expressions can also be compound: {5 + 3; 4 * 2; 1 + 1} ## [1] 2

15

slide-18
SLIDE 18

Expressions

The value of an expression is the last evaluated statement:

# value of an expression {5 + 3; 4 * 2; 1 + 1} ## [1] 2

The result has the visibility of the last evaluation

16

slide-19
SLIDE 19

Simple Expressions

We use braces { } to group the statements of an expression:

# simple expression {5 + 3} ## [1] 8

For simple expressions there is really no need to use braces

17

slide-20
SLIDE 20

Compound Expressions

◮ Compound expressions consist of multiple simple

expressions

◮ Compound expressions require braces ◮ Simple expressions in a compound expression can be

separated by semicolons or newlines

18

slide-21
SLIDE 21

Compound Expressions

Simple expressions in a compound expression separated by semicolons:

# compound expression {mean(1:10); '3'; print("hello"); c(1, 3, 4)} ## [1] "hello" ## [1] 1 3 4

19

slide-22
SLIDE 22

Compound Expressions

Simple expressions in a compound expression separated by newlines:

# compound expression { mean(1:10) '3' print("hello") c(1, 3, 4) } ## [1] "hello" ## [1] 1 3 4

20

slide-23
SLIDE 23

Compound Expressions

It is possible to have assignments within compound expressions:

{ x <- 4 y <- x^2 x + y } ## [1] 20

21

slide-24
SLIDE 24

Compound Expressions

The variables inside the braces can be used in later expressions

z <- {x <- 4; y <- x^2; x + y} x ## [1] 4 y ## [1] 16 z ## [1] 20

22

slide-25
SLIDE 25

Compound Expressions

# simple expressions in newlines z <- { x <- 4 y <- x^2 x + y} x ## [1] 4 y ## [1] 16 z ## [1] 20

23

slide-26
SLIDE 26

Using Expressions

Expressions are typically used in

◮ Flow control structures (e.g. for loop) ◮ Functions 24

slide-27
SLIDE 27

Compound Expressions

Do not confuse a function call (having arguments in multiple lines) with a compound expression

# this is NOT a compound expression plot(x = runif(10), y = rnorm(10), pch = 19, col = "#89F39A", cex = 2, main = "some plot", xlab = 'x', ylab = 'y')

25

slide-28
SLIDE 28

Control Flow Structures

26

slide-29
SLIDE 29

Control Flow

There are many times where you don’t just want to execute one statement after another: you need to control the flow of execution.

27

slide-30
SLIDE 30

Main Idea Execute some code when a condition is fulfilled

28

slide-31
SLIDE 31

Control Flow Structures

◮ if-then-else ◮ switch cases ◮ repeat loop ◮ while loop ◮ for loop 29

slide-32
SLIDE 32

If-Then-Else

30

slide-33
SLIDE 33

If-Then-Else

If-then-else statements make it possible to choose between two (possibly compound) expressions depending on the value of a (logical) condition.

# if-then-else if (condition) expression1 else expression2

If condition is true then expression1 is evaluated otherwise expression2 is executed.

31

slide-34
SLIDE 34

If-Then-Else

If-then-else with simple expressions (equivalent forms):

# no braces if (condition) expression1 else expression2 # with braces if (condition) { expression1 } else { expression2 }

32

slide-35
SLIDE 35

If-Then-Else

If-then-else with compound expressions:

# compound expressions require braces if (condition) { expression1 expression2 ... } else { expression3 expression4 ... }

33

slide-36
SLIDE 36

Example: If-Then-Else

Equivalent forms:

# simple if-then-else if (5 > 2) 5 * 2 else 5 / 2 ## [1] 10 # simple if-then-else if (5 > 2) { 5 * 2 } else { 5 / 2 } ## [1] 10

34

slide-37
SLIDE 37

Example: If-Then-Else

Equivalent forms:

# simple if-then-else if (x > 0) y <- sqrt(x) else y <- abs(x) # simple if-then-else if (x > 0) { y <- sqrt(x) } else { y <- abs(x) }

35

slide-38
SLIDE 38

If-Then-Else

◮ if() takes a logical condition ◮ the condition must be a logical value of length one ◮ it executes the next statement if the condition is true ◮ if the condition is false, then it executes the false expression 36

slide-39
SLIDE 39

2 types of If conditions

if-then-else

# if and else if (condition) { expression_true } else { expression_false }

Just if

# simple if if (condition) { expression_true }

It is also possible to just have the if clause (without else)

37

slide-40
SLIDE 40

Just If

Just if

# just if if (condition) { expression1 ... }

Equivalent to:

# just if (else NULL) if (condition) { expression1 ... } else NULL

38

slide-41
SLIDE 41

If and Else

◮ if() takes a logical condition ◮ the condition must be a logical value of length one ◮ it executes the next statement if the condition is true ◮ if the condition is false, and there is no else, then it stops ◮ if the condition is false, and there is an else, then it

executes the false expression

39

slide-42
SLIDE 42

Reminder of Comparison Operators

  • peration

usage less than x < x greater than x > y less than or equal x <= y greater than or equal x >= y equality x == y different x != y Comparison operators produce logical values

40

slide-43
SLIDE 43

Reminder of Logical Operators

  • peration

usage NOT !x AND (elementwise) x & y AND (1st element) x && y OR (elementwise) x | y OR (1st element) x || y exclusive OR xor(x, y) Logical operators produce logical values

41

slide-44
SLIDE 44

Just if’s behavior

# this prints if (TRUE) { print("It is true") } # this does not print if (FALSE) { print("It is false") } # this does not print if (!TRUE) { print("It is not true") } # this prints if (!FALSE) { print("It is not false") }

42

slide-45
SLIDE 45

Just if

x <- 7 if (x >= 0) { print("it is positive") } ## [1] "it is positive" if (is.numeric(x)) { print("it is numeric") } ## [1] "it is numeric"

43

slide-46
SLIDE 46

If and Else

y <- -5 if (y >= 0) { print("it is positive") } else { print("it is negative") } ## [1] "it is negative"

The else statement must occur on the same line as the closing brace from the if clause!

44

slide-47
SLIDE 47

If and Else

The logical condition must be of length one!

if (c(TRUE, TRUE)) { print("it is positive") } else { print("it is negative") } ## Warning in if (c(TRUE, TRUE)) {: the condition has length > 1 and only the first element will be used ## [1] "it is positive"

45

slide-48
SLIDE 48

If and Else

What’s the length of the logical condition?

x <- 3 y <- 4 if (x > 0 & y > 0) { print("they are not negative") } else { print("they may be negative") } ## [1] "they are not negative"

46

slide-49
SLIDE 49

If and Else

If there’s is a single statement, you can omit the braces:

if (TRUE) { print("It is true") } if (TRUE) print("It is true") # valid but not recommended if (TRUE) print("It is true")

47

slide-50
SLIDE 50

Equivalent ways

No braces:

# ok if (TRUE) print("It's true") # valid but not recommended if (TRUE) print("It's true")

With braces:

# ok if (TRUE) {print("It's true")} # recommended if (TRUE) { print("It's true") }

48

slide-51
SLIDE 51

If and Else

If there are multiple statements, you must use braces:

if (x > 0) { a <- x^(2) b <- 3 * a + 34.8 - exp(2) }

49

slide-52
SLIDE 52

Multiple If’s

Multiple conditions can be defined by combining if and else repeatedly:

set.seed(9) x <- round(rnorm(1), 1) if (x > 0) { print("x is positive") } else if (x < 0) { print("x is negative") } else if (x == 0) { print("x is zero") } ## [1] "x is negative"

50

slide-53
SLIDE 53

Vectorized ifelse()

if() takes a single logical value. If you want to pass a logical vector of conditions, you can use ifelse():

true_false <- c(TRUE, FALSE) ifelse(true_false, "true", "false") ## [1] "true" "false"

51

slide-54
SLIDE 54

Vectorized If

# some numbers numbers <- c(1, 0, -4, 9, -0.9) # are they non-negative or negative? ifelse(numbers >= 0, "non-neg", "neg") ## [1] "non-neg" "non-neg" "neg" "non-neg" "neg"

52

slide-55
SLIDE 55

Test yourself

Which option will cause an error:

# A if (is.numeric(1:5)) { print('ok') } # B if ("TRUE") { print('ok') } # C if (0) print('ok') # D if (NA) print('ok') # E if ('yes') { print('ok') }

53

slide-56
SLIDE 56

Switch

54

slide-57
SLIDE 57

Multiple Selection with switch()

When a condition has multiple options, combining several if and else can become cumbersome

55

slide-58
SLIDE 58

first_name <- "harry" if (first_name == "harry") { last_name <- "potter" } else { if (first_name == "ron") { last_name <- "weasley" } else { if (first_name == "hermione") { last_name <- "granger" } else { last_name <- "not available" } } } last_name ## [1] "potter"

56

slide-59
SLIDE 59

Multiple Selection with switch()

first_name <- "ron" last_name <- switch( first_name, harry = "potter", ron = "weasley", hermione = "granger", "not available") last_name ## [1] "weasley"

57

slide-60
SLIDE 60

Multiple Selection with switch()

◮ the switch() function makes it possible to choose

between various alternatives

◮ switch() takes a character string ◮ followed by several named arguments ◮ switch() will match the input string with the provided

arguments

◮ a default value can be given when there’s no match ◮ multiple expression can be enclosed by braces 58

slide-61
SLIDE 61

Multiple Selection with switch()

switch(expr, tag1 = rcode_block1, tag2 = rcode_block2, ... )

switch() selects one of the code blocks, depending on the value of expr

59

slide-62
SLIDE 62

Multiple Selection with switch()

  • peration <- "add"

result <- switch(

  • peration,

add = 2 + 3, product = 2 * 3, division = 2 / 3,

  • ther = {

a <- 2 + 3 exp(1 / sqrt(a)) } ) result ## [1] 5

60

slide-63
SLIDE 63

Multiple Selection with switch()

◮ switch() can also take an integer as first argument ◮ in this case the remaining arguments do not need names ◮ instead, the they will have associated integers

switch( 4, "one", "two", "three", "four") ## [1] "four"

61

slide-64
SLIDE 64

Empty code blocks in switch()

Empty code blocks can be used to make several tags match the same code block:

student <- "ron" house <- switch( student, harry = , ron = , hermione = "gryffindor", draco = "slytherin")

In this case a value of "harry", "ron" or "hermione" will cause "gryffindor"

62

slide-65
SLIDE 65

Loops

63

slide-66
SLIDE 66

About Loops

◮ Many times we need to perform a procedure several times ◮ The main idea is that of iteration ◮ For this purpose we use loops ◮ We perform operations as long as some condition is fulfilled ◮ R provides three basic paradigms:

– for, repeat, while

64

slide-67
SLIDE 67

Repeat Loops

65

slide-68
SLIDE 68

Repeat Loops

repeat executes the same code over and over until a stop condition is met.

repeat { keep_doing_something if (stop_condition) break }

The break statement stops the loops

66

slide-69
SLIDE 69

Repeat Loops

value <- 2 repeat { value <- value * 2 print(value) if (value >= 40) break } ## [1] 4 ## [1] 8 ## [1] 16 ## [1] 32 ## [1] 64

If you enter an infinite loop, break it by pressing ESC key

67

slide-70
SLIDE 70

Repeat Loops

To skip a current iteration, use next

value <- 2 repeat { value <- value * 2 print(value) if (value == 16) { value <- value * 2 next } if (value > 80) break } ## [1] 4 ## [1] 8 ## [1] 16 ## [1] 64 ## [1] 128

68

slide-71
SLIDE 71

While Loops

69

slide-72
SLIDE 72

While Loops

It can also be useful to repeat a computation until a condition is false. A while loop provides this form of control flow

while (condition) { keep_doing_something }

70

slide-73
SLIDE 73

While Loops

◮ while loops are like backward repeat loops; ◮ while checks first and then attempts to execute ◮ computations are carried out for as long as the condition is

true

◮ the loop stops when the condition is false ◮ If you enter an infinite loop, break it by pressing ESC key 71

slide-74
SLIDE 74

While Loops

value <- 2 while (value < 40) { value <- value * 2 print(value) } ## [1] 4 ## [1] 8 ## [1] 16 ## [1] 32 ## [1] 64

If you enter an infinite loop, break it by pressing ESC key

72

slide-75
SLIDE 75

For Loops

73

slide-76
SLIDE 76

For Loops

Often we want to repeatedly carry out some computation a fixed number of times. For instance, repeat an operation for each element of a vector. In R this is done with a for loop

74

slide-77
SLIDE 77

For Loops

for loops are used when we know exactly how many times we want the code to repeat

for (iterator in times) { do_something }

for takes an iterator variable and a vector of times to iterate through

75

slide-78
SLIDE 78

For Loops

value <- 2 for (i in 1:5) { value <- value * 2 print(value) } ## [1] 4 ## [1] 8 ## [1] 16 ## [1] 32 ## [1] 64

76

slide-79
SLIDE 79

For Loops

The vector of times does not have to be a numeric vector; it can be any vector

value <- 2 times <- c('1', '2', '3', '4', '5') for (i in times) { value <- value * 2 print(value) } ## [1] 4 ## [1] 8 ## [1] 16 ## [1] 32 ## [1] 64

77

slide-80
SLIDE 80

For Loops and Next statement

Sometimes we need to skip a loop iteration if a given condition is met, this can be done with a next statement

for (iterator in times) { expr1 expr2 if (condition) { next } expr3 expr4 }

78

slide-81
SLIDE 81

For Loops and Next statement

x <- 2 for (i in 1:5) { y <- x * i if (y == 8) { next } print(y) } ## [1] 2 ## [1] 4 ## [1] 6 ## [1] 10

79

slide-82
SLIDE 82

For Loops

For loop

# squaring values x <- 1:5 y <- x for (i in 1:5) { y[i] <- x[i]^2 } y ## [1] 1 4 9 16 25

Vectorized computation

# squaring values x <- 1:5 y <- x^2 y ## [1] 1 4 9 16 25

80

slide-83
SLIDE 83

Nested Loops

It is common to have nested loops

for (iterator1 in times1) { for (iterator2 in times2) { expr1 expr2 ... } }

81

slide-84
SLIDE 84

Nested Loops

# some matrix A <- matrix(1:12, nrow = 3, ncol = 4) A ## [,1] [,2] [,3] [,4] ## [1,] 1 4 7 10 ## [2,] 2 5 8 11 ## [3,] 3 6 9 12

82

slide-85
SLIDE 85

Nested Loops

# nested loops for (i in 1:nrow(A)) { for (j in 1:ncol(A)) { if (A[i,j] < 6) A[i,j] <- 1 / A[i,j] } } A ## [,1] [,2] [,3] [,4] ## [1,] 1.0000000 0.25 7 10 ## [2,] 0.5000000 0.20 8 11 ## [3,] 0.3333333 6.00 9 12

83

slide-86
SLIDE 86

For Loops and Vectorized Computations

◮ R for loops have a bad reputation for being slow ◮ Experienced users will tell you to avoid for loops in R (me

included)

◮ R provides a family of functions that tend to be more

efficient than loops (i.e. apply() functions)

84

slide-87
SLIDE 87

For Loops and Vectorized Computations

◮ For purposes of learning programming (and flow control

structures in R), I won’t demonize R loops

◮ You can start solving a problem using a for loop ◮ Once you solved it, try to see if you can find a vectorized

alternative

◮ It takes practice and experience to find alternative solutions

to for loops

◮ There are cases when using for loops is inevitable 85

slide-88
SLIDE 88

Repeat, While, For

◮ If you don’t know the number of times something will be

done you can use either repeat or while

◮ while evaluates the condition at the beginning ◮ repeat executes operations until a stop condition is met ◮ If you know the number of times that something will be

done, use for

◮ for needs an iterator and a vector of times 86

slide-89
SLIDE 89

For Loop

This example is just for demo purposes (not recommended in R)

# empty numeric vector x <- numeric(0) x ## numeric(0) # for loop to fill x for (i in 1:5) { x[i] <- i } x ## [1] 1 2 3 4 5

87

slide-90
SLIDE 90

For Loop

If you know the number of times

# empty numeric vector x <- numeric(5) x ## [1] 0 0 0 0 0 # for loop to fill x for (i in 1:5) { x[i] <- i } x ## [1] 1 2 3 4 5

88

slide-91
SLIDE 91

Quiz

◮ What happens if you pass NA as a condition to if()? ◮ What happens if you pass NA as a condition to ifelse()? ◮ What types of values can be passed as the first argument

to the switch() function?

◮ How do you stop a repeat loop executing? ◮ How do you jump to the next iteration of a loop? 89