<style type="text/css">

div#TOC li {
    list-style:none;
    background-image:none;
    background-repeat:none;
    background-position:0;
}
h1.title {
  font-size: 24px;
  color: DarkRed;
  text-align: center;
}
h4.author { /* Header 4 - and the author and data headers use this too  */
    font-size: 18px;
  font-family: "Times New Roman", Times, serif;
  color: DarkRed;
  text-align: center;
}
h4.date { /* Header 4 - and the author and data headers use this too  */
  font-size: 18px;
  font-family: "Times New Roman", Times, serif;
  color: DarkBlue;
  text-align: center;
}
h1 { /* Header 1 - and the author and data headers use this too  */
    font-size: 22px;
    font-family: "Times New Roman", Times, serif;
    color: darkred;
    text-align: center;
}
h2 { /* Header 2 - and the author and data headers use this too  */
    font-size: 18px;
    font-family: "Times New Roman", Times, serif;
    color: navy;
    text-align: left;
}

h3 { /* Header 3 - and the author and data headers use this too  */
    font-size: 15px;
    font-family: "Times New Roman", Times, serif;
    color: navy;
    text-align: left;
}

h4 { /* Header 4 - and the author and data headers use this too  */
    font-size: 18px;
    font-family: "Times New Roman", Times, serif;
    color: darkred;
    text-align: left;
}
</style>

```{r setup, include=FALSE}
# code chunk specifies whether the R code, warnings, and output 
# will be included in the output files.
if (!require("tidyverse")) {
   install.packages("tidyverse")
   library(tidyverse)
}
if (!require("knitr")) {
   install.packages("knitr")
   library(knitr)
}
if (!require("plotly")) {
   install.packages("plotly")
   library(plotly)
}
if (!require("gapminder")) {
   install.packages("gapminder")
   library(gapminder)
}
if (!require("colourpicker")) {
    install.packages("colourpicker")              
    library("colourpicker")
}
if (!require("gganimate")) {
    install.packages("gganimate")              
    library("gganimate")
}
# knitr::opts_knit$set(root.dir = "C:/Users/75CPENG/OneDrive - West Chester University of PA/Documents")
# knitr::opts_knit$set(root.dir = "C:\\STA490\\w05")
##
knitr::opts_chunk$set(echo = TRUE,       
                      warning = FALSE,   
                      result = TRUE,   
                      message = FALSE)
```



# Control flow

## Introduction

There are two primary tools of control flow: choices and loops.

**Choices**, like if statements and `switch()` calls, allow us to run different code depending on the input. 

**Loops**, like for and while, allow us to repeatedly run code, typically with changing options.


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


## Choices

The basic form of an if statement in R is as follows:

if (condition) true_action
if (condition) true_action else false_action
If the condition is TRUE, true_action is evaluated; if the condition is FALSE, the optional false_action is evaluated.

Typically the actions are compound statements contained within {:

```{r}
grade <- function(x) {
  if (x > 90) {
    "A"
  } else if (x > 80) {
    "B"
  } else if (x > 50) {
    "C"
  } else {
    "F"
  }
}
```

`if` returns a value so that you can assign the results:

```{r}
x1 <- if (TRUE) 1 else 2
x2 <- if (FALSE) 1 else 2
c(x1, x2)
```


When we use the single argument form without an else statement, if invisibly returns NULL if the condition is FALSE. Since functions like `c()` and `paste()` drop NULL inputs, this allows for a compact expression of certain idioms:

```{r}
greet <- function(name, birthday = FALSE) {
  paste0(
    "Hi ", name,
    if (birthday) " and HAPPY BIRTHDAY"
  )
}
greet("Maria", FALSE)
greet("Jaime", TRUE)
```


**Invalid inputs**

The condition should evaluate to a single TRUE or FALSE. Most other inputs will generate an error:

```{r}
#if ("x") 1
#> Error in if ("x") 1: argument is not interpretable as logical
#if (NA) 1
#> Error in if (NA) 1: missing value where TRUE/FALSE needed
```


The exception is a logical vector of length greater than 1, which generates a warning:

```{r}
if (c(TRUE, FALSE)) 1
```
**Vectorized if**

Given that if only works with a single TRUE or FALSE, you might wonder what to do if you have a vector of logical values. Handling vectors of values is the job of `ifelse()`: a vectorized function with test, yes, and no vectors (that will be recycled to the same length):

```{r}
x <- 1:10
ifelse(x %% 5 == 0, "XXX", as.character(x))
```

```{r}
ifelse(x %% 2 == 0, "even", "odd")
```

Note that missing values will be propagated into the output.



Another vectorized equivalent is the more general *dplyr::case_when()*. It uses a special syntax to allow any number of condition-vector pairs:

```{r}
dplyr::case_when(
  x %% 35 == 0 ~ "fizz buzz",
  x %% 5 == 0 ~ "fizz",
  x %% 7 == 0 ~ "buzz",
  is.na(x) ~ "???",
  TRUE ~ as.character(x)
)
```


```{r}
9 %/% 5     ## quotient
```
```{r}
9%%5     ## remainder 
```

**switch() statement**

Closely related to if is the switch()-statement. It’s a compact, special purpose equivalent that lets you replace code like:

```{r}
x_option <- function(x) {
  if (x == "a") {
    "option 1"
  } else if (x == "b") {
    "option 2" 
  } else if (x == "c") {
    "option 3"
  } else {
    stop("Invalid `x` value")
  }
}
```

with the more succinct:

```{r}
x_option <- function(x) {
  switch(x,
    a = "option 1",
    b = "option 2",
    c = "option 3",
    stop("Invalid `x` value")
  )
}
```

The last component of a `switch()` should always throw an error, otherwise unmatched inputs will invisibly return NULL:

```{r}
(switch("c", a = 1, b = 2))
```


If multiple inputs have the same output, you can leave the right hand side of = empty and the input will “fall through” to the next value. This mimics the behavior of C’s switch statement:

```{r}
legs <- function(x) {
  switch(x,
    cow = ,
    horse = ,
    dog = 4,
    human = ,
    chicken = 2,
    plant = 0,
    stop("Unknown input")
  )
}
legs("cow")
```
```{r}
legs("dog")
```


It is also possible to use `switch()` with a numeric x, but is harder to read, and has undesirable failure modes if x is not a whole number. 


## Loops

`for loops` are used to iterate over items in a vector. They have the following basic form:

```
for (item in vector) perform_action
```

For each item in vector, perform_action is called once; updating the value of the item each time.

```{r}
for (i in 1:3) {
  print(i)
}
```

`for` assigns the item to the current environment, overwriting any existing variable with the same name:

```{r}
i <- 100
for (i in 1:3) {}
i
```


There are two ways to terminate a for a loop early:

* `next` exits the current iteration.

* `break` exits the entire for a loop.

```{r}
for (i in 1:10) {
  if (i < 3) 
    next

  print(i)
  
  if (i >= 5)
    break
}
```

# Functions


##  Introduction

We have already created R functions and know how to use them to reduce duplication in our code. In this note, we’ll learn how to turn that informal, working knowledge into a more rigorous understanding of R functions. 



## Function fundamentals

To understand functions in R we need to internalize two important ideas:

Functions can be broken down into three components: arguments, body, and environment. Functions are objects, just as vectors are objects.

### Function components

A function has three parts:

* `The formals()`, the list of arguments that control how you call the function.

* `The body()`, the code inside the function.

* `The environment()`, the data structure that determines how the function finds the values associated with the names.

While the formals and body are specified explicitly when you create a function, the environment is specified implicitly, based on where you defined the function. The function environment always exists, but it is only printed when the function isn’t defined in the global environment.

```{r}
f02 <- function(x, y) {
  x + y
}
```

```{r}
formals(f02)
```

```{r}
body(f02)
```

```{r}
environment(f02)
```



### First-class functions

It’s very important to understand that R functions are objects in their own right, a language property often called “first-class functions”. Unlike in many other languages, there is no special syntax for defining and naming a function: we simply create a function object (with function) and bind it to a name with <-:

```{r}
f01 <- function(x) {
  sin(1 / x ^ 2)
}
```


While you almost always create a function and then bind it to a name, the binding step is not compulsory. If you choose not to give a function a name, you get an anonymous function. This is useful when it’s not worth the effort to figure out a name:


```{r}
lapply(mtcars, function(x) length(unique(x)))
```


```{r}
Filter(function(x) !is.numeric(x), mtcars)
```


```{r}
integrate(function(x) sin(x) ^ 2, 0, pi)$value
```




```{r}
names(iris)
```

```{r}
iris$Species
```





A final option is to put functions in a list:

```{r}
funs <- list(
  half = function(x) x / 2,
  double = function(x) x * 2
)

funs$double(10)
```

```{r}
funs$half(10)
```

## Function Composition

Base R provides two ways to compose multiple function calls. For example, imagine we want to compute the population standard deviation using `sqrt()` and `mean()` as building blocks:

```{r}
square <- function(x) x^2
square(7)
```




```{r}
sqrt0 = function(x){
  x^2
}
##
sqrt0(7)
```


```{r}
deviation <- function(x) x - mean(x)
```


You either nest the function calls:

```{r}
x <- runif(100)
sqrt(mean(square(deviation(x))))
```


Or we save the intermediate results as variables:

```{r}
out <- deviation(x)
out <- square(out)
out <- mean(out)
out <- sqrt(out)
out
```


The `magrittr` package provides a third option: the binary operator `%>%`, which is called the pipe and is pronounced as `“and then”`.

```{r}
library(magrittr)
square <- function(x) x^2
deviation <- function(x) x - mean(x)
x <- 1:50
##
x %>%
  deviation() %>%  # deviation () is defined function above
  square() %>%
  mean() %>%
  sqrt()
```

**pipe operator %>%**:`x %>% f()` is equivalent to f(x); `x %>% f(y)` is equivalent to f(x, y). 


### Infix functions

Infix functions get their name from the fact the function name comes in between its arguments, and hence have two arguments. R comes with a number of built-in infix operators: 

* `:` - an operator that generates a patterned sequence. It is also used to indicate an `interaction` of two variables.
* `::` - an operator to access an object in a known package. For example, `stats::sd`. 
* `:::` - an operator to access an object in a package - it is rarely used.,  
* `$` - extracts elements by name from a named list. 
* `^` - exponential operator (to-the-power-of)  
* `*` - multiplication (operator)
* `/` - division (operator)
* `+` - addition (operator) 
* `-` - subtraction (operator) 
* `>` - logical and numerical GREATER THAN  
* `>=` - logical and numerical GREATER OR EQUAL TO 
* `<` - logical and numerical EQUAL TO
* `<=` - logical and numerical LESS THAN OR EQUAL TO
* `==` - logical EQUAL TO 
* `!=` - logical and numerical NOT EQUAL TO 
* `!` - logical negation (NOT) 
* `&` - logical AND (element-wise).
* `&&` - logical AND.
* `|` - logical OR (element-wise).
* `||` - logical OR.
* `~` -  operator used in the formation of a model
* `<-` - leftwards assignment
* `<<-`- leftwards assignment (used for assigning to variables in the parent environments)
* `->` - rightwards assignment
* `->>` - rightwards assignment (used for assigning to variables in the parent environments)
* `%%` - modulus (Remainder from division)
* `%/%`	- integer Division


We can also create your own infix functions that start and end with %. Base R uses this pattern to define %%, %*%, %/%, %in%, %o%, and %x%.

Defining our own infix function is simple. We create a two-argument function and bind it to a name that starts and ends with `%`. For example,


```{r}
`%+%` <- function(a, b) paste0(a, b)
"new " %+% "string"
```


The names of infix functions are more flexible than regular R functions: they can contain any sequence of characters except for %. You will need to escape any special characters in the string used to define the function, but not when you call it:

```{r}
`% %` <- function(a, b) paste(a, b)
`%/\\%` <- function(a, b) paste(a, b)
```


```{r}
"a" % % "b"
```


```{r}
"a" %/\% "b"
```

R’s default precedence rules mean that infix operators are composed left to right.

```{r}
`%-%` <- function(a, b) paste0("(", a, " %-% ", b, ")")
"a" %-% "b" %-% "c"
```

