class: center, middle, inverse, title-slide # STA 517 3.0 Programming and Statistical Computing with R ## 🔩 Control Structures in R ### ### Dr Thiyanga Talagala --- <style type="text/css"> .remark-slide-content { font-size: 30px; } </style> ### Today's menu **Control structures (loops/ conditional executions)** .pull-left[ if, else for while repeat break next switch ] .pull-right[ <top><img src="forloop.jpeg" height="400px"/></top> ] --- class: inverse, center, middle # Conditional executions control the flow of the execution. --- background-image: url(ifloop.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Draw a star on star-shaped cookies and draw a heart on heart-shaped cookies. .tr[ ]] --- background-image: url(ifloop.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## if-else .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Draw a star on star-shaped cookies and draw a heart on heart-shaped cookies. .tr[ ]] --- .pull-left[ # if-else ```r if (condition) { # do something } else { # do something else } ``` ] .pull-right[ Example ```r test_even_odd <- function(x){ if (x %% 2 == 0){ print("even number") } else { print("odd number") } } ``` ```r test_even_odd(5) ``` ``` [1] "odd number" ``` ```r test_even_odd(6) ``` ``` [1] "even number" ``` ] --- # `ifelse`: vectorization with `ifelse` ```r ifelse(condition, TRUE condition output, FALSE condition output) ``` Example ```r test_even_odd_v2 <- function(x){ ifelse(x %% 2 == 0, "even number", "odd number") } ``` ```r test_even_odd_v2(5) ``` ``` FALSE [1] "odd number" ``` ```r test_even_odd_v2(c(1,6)) ``` ``` FALSE [1] "odd number" "even number" ``` --- ## Difference between `if, else` and `ifelse` .pull-left[ **`if, else`** ```r test_even_odd <- function(x){ if (x %% 2 == 0) { print("even number") } else { print("odd number") } } ``` ```r test_even_odd(5) ``` ``` FALSE [1] "odd number" ``` ```r test_even_odd(c(1,6)) ``` ``` FALSE [1] "odd number" ``` ] .pull-right[ **`ifelse`** ```r test_even_odd_v2 <- function(x){ ifelse (x %% 2 == 0, "even number", "odd number") } test_even_odd_v2(5) ``` ``` FALSE [1] "odd number" ``` ```r test_even_odd_v2(c(1,6)) ``` ``` FALSE [1] "odd number" "even number" ``` ] --- # Nested if-else - Multiple conditions ```r grade_marks <- function(marks){ if (marks < 20) { "D" } else if (marks <= 50) { "C" } else if (marks <= 60) { "B" } else { "A" } } grade_marks(75) ``` ``` [1] "A" ``` --- class: inverse, center, middle # Your turn --- R for Data Science-Exercises 19.4.4 - Q2 <iframe src="https://r4ds.had.co.nz/functions.html" width="100%" height="400px" data-external="1"></iframe> Help: `lubridate::now()` and `lubridate::hour()`
10
:
00
--- ## if ```r check.negative <- function(x){ if (x < 0 ) { print("X is negative") } } ``` ```r check.negative(-10) ``` ``` [1] "X is negative" ``` ```r check.negative(10) ``` --- background-image: url(forloop.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ For the first 50 cookies, fill the center of cookies with jam. .tr[ ]] --- background-image: url(forloop.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## for .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ For the first 50 cookies, fill the center of cookies with jam. .tr[ ]] --- # `for` loop - execute a block of code a specific number of times or until the end of a sequence. ```r for (i in 1:5) { print(i*100) } ``` ``` [1] 100 [1] 200 [1] 300 [1] 400 [1] 500 ``` --- ```r continents <- c("Asia", "EU", "AUS", "NA", "SA", "Africa") ``` .pull-left[ ```r for (i in 1:4) { print(continents[i]) } ``` ``` [1] "Asia" [1] "EU" [1] "AUS" [1] "NA" ``` ```r for (i in 1:4) print(continents[i]) ``` ``` [1] "Asia" [1] "EU" [1] "AUS" [1] "NA" ``` ] .pull-right[ ```r for (i in seq(continents)) { print(continents[i]) } ``` ``` [1] "Asia" [1] "EU" [1] "AUS" [1] "NA" [1] "SA" [1] "Africa" ``` ] --- class: inverse, center, middle # Your turn --- Write a for loop that iterates over the numbers 1 to 4 and prints the squared of each number using `print()`.
03
:
00
--- background-image: url(ifloop.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ For the first 50 cookies, draw a star on star-shaped cookies and draw a heart on heart-shaped cookies. .tr[ ]] --- background-image: url(ifloop.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## nested loops .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ For the first 50 cookies, draw a star on star-shaped cookies and draw a heart on heart-shaped cookies. .tr[ ]] --- ## Nested loops ```r a <- 1:10 testfun <- function(x){ for (x in 1:5) { if (x %% 2 == 0) { print("even number") } else { print("odd number") } }} testfun(a) ``` ``` [1] "odd number" [1] "even number" [1] "odd number" [1] "even number" [1] "odd number" ``` --- # Nested loops ```r mat <- matrix(1:6, ncol=2) mat ``` ``` [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 ``` ```r for (i in 1:3) { for (j in 1:2) { print(mat[i, j]) } } ``` ``` [1] 1 [1] 4 [1] 2 [1] 5 [1] 3 [1] 6 ``` --- class: inverse, center, middle # Your turn --- Write a function to count the number of even numbers in a vector.
08
:
00
--- background-image: url(cookie9.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Taste the cookies one by one until you find the star-shaped cookie. .tr[ ]] --- background-image: url(cookie9.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## while .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Taste the cookies one by one until you find the star-shaped cookie. .tr[ ]] --- # while .pull-left[ ```r i <- 1 # initial value while (i != 10) { print(i) i <- i + 1 # increment } ``` ``` [1] 1 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 ``` ] .pull-right[ ```r i <- 1 # initial value while (i < 10) { print(i) i <- i + 1 # increment } ``` ``` [1] 1 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 ``` ] --- class: inverse, center, middle # Your turn --- Can you guess the output? ```r i <- 1 # initial value while (i == 10) { print(i) i <- i + 1 # increment } ```
01
:
00
--- class: inverse, center, middle # Your turn --- Generate the first `n` numbers of the Fibonacci Sequence using while loop. 0 1 1 2 3 5 ...
04
:
00
--- background-image: url(cookie9.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Taste the cookies one by one until you find the strawberry flavoured cookie. .tr[ ]] --- background-image: url(cookie9.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## repeat-break .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Taste the cookies one by one until you find the strawberry flavoured cookie. .tr[ ]] --- # repeat and break - Iterate over a block of code multiple number of times. - No condition check in repeat loop to exit the loop. - The only way to exit a repeat loop is to call break. --- ## repeat and break .pull-left[ Example 1 ```r x <- 5 repeat { print(x) x = x+1 if (x == 10){ break } } ``` ``` [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 ``` ] -- .pull-right[ Example 2 ```r set.seed(1) repeat { x<-runif(1, 5, 10) print(x) if(x < 6.1){ break } } ``` ``` [1] 6.327543 [1] 6.860619 [1] 7.864267 [1] 9.541039 [1] 6.00841 ``` ] --- ## Your turn 1. Write a function to print random numbers from the standard normal distribution but stops (breaks) if you get a number bigger than 1. 2. Using next adapt the loop from last exercise so that doesn’t print negative numbers. --- background-image: url(decorating-2702974_1920.jpg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Skip cracked muffins and decorate the rest. .tr[ ]] --- background-image: url(decorating-2702974_1920.jpg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## next .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Skip cracked muffins and decorate the rest. .tr[ ]] --- # next ```r for(i in 1:10) { if(i <= 5) { next # Skip the first 5 iterations } print(i) } ``` ``` [1] 6 [1] 7 [1] 8 [1] 9 [1] 10 ``` --- background-image: url(switch.jpeg) background-size: cover .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Green base - roses, small - dots, medium - stars, ... .tr[ ]] --- background-image: url(switch.jpeg) background-size: cover .bg-yellow.b--dark-yellow.ba.bw2.br3.shadow-5.ph4.mt5[ ## switch .tr[ ]] .bg-washed-green.b--dark-green.ba.bw2.br3.shadow-5.ph4.mt5[ Green base - roses, small - dots, etc.. .tr[ ]] --- # switch When you want a function to do different things in different circumstances, then the switch function can be useful. ```r feelings <- c("sad", "afraid") for (i in feelings){ print( switch(i, happy = "I am glad you are happy", afraid = "There is nothing to fear", sad = "Cheer up", angry = "Calm down now" )) } ``` ``` [1] "Cheer up" [1] "There is nothing to fear" ``` --- .pull-left[ ## Single element - working ```r x <- "a" v <- switch(x, "a" = "apple", "b" = "banana", "c" = "cherry") v ``` ``` [1] "apple" ``` ## Multiple elements - not working ```r switch(c("a", "b"), "a" = "apple", # not working "b" = "banana", "c" = "cherry") ``` ] .pull-right[ ## Multiple element - use `for` loop ```r vect <- c("a", "b") for(i in seq(vect)){ print(switch(i, "a" = "apple", # not working "b" = "banana", "c" = "cherry")) } ``` ] --- class: center, middle ## Thank you! Slides available at: hellor.netlify.app All rights reserved by [Thiyanga S. Talagala](https://thiyanga.netlify.app/)