---
title: "SML201 Week 1 Lecture 2"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```


## Comments

Comments are meant to help humans understand R code. Anything that follow the pound sign `#` is ignored by R. You can use comments to explain your code (to your partner, preceptor, or your future self), or to temporarily disable parts of your code.

```{r}
cat("hi") # This part will be ignored by R

# You can write comments here too
cat("Things are happenning again")
```

## Syntax

"Syntax" is the set of rules according to which R statements must be constructed. For example, as we saw in the previous lecture, to construct an if-statement, you must write things as

    if(<CONDITION1>){
      <STATEMENT1>
      <STATEMENT2>
      ...
    }else if(<CONDITION2>){
      <STATEMENT3>
      <STATEMENT4>
      ...
    }else if(<CONDITION3>){
      <STATEMENT5>
      <STATEMENT6>
      ...
    }...else{
     <STATEMENT7>
     ...
    }


The curly braces and brackets are mandatory. Violating syntax rules would usually result in R producing an error.

(Syntax is distinct from semantics -- the rules that determine the *meaning* of R statements. This is analoguous to terms used for human languages.)


## Vectors

Here is an example of a vector

```{r}
offer <- c(241, 590, 533, 425, 261)
```

A vector is a sequence of values of the same type (you can also have vectors of characters). Here is how you can access elements of a vector:

```{r}
offer[1]
offer[4]
```


You can find the length (i.e., the number of elements of a vector) like so:

```{r}
length(offer)
```

Aside: technically, everything in R is a vector. It's just that some vectors have length 1.

```{r}
a <- 42
a[1]
```

You can even do the following, if you insist:
```{r}
42[1]
```

Here are some things we can do with vectors:

```{r}
sort(offer) # Compute a sorted version of the vector, in increasing order
```

```{r}
unique(c(1, 2, 1, 4, 5, 2)) # Get a vector with every element of the input appearing once
```

```{r}
max(offer)
min(offer)
```

Here is how we can compute the `max` without using the `max` function:

```{r}
sort(offer)[length(offer)]
```

(Explain this!)


We can also perform operations on all the elements of a vector.

```{r}
offer > 533
```

```{r}
offer == 533
```

## Indexing vectors with logical vectors

A powerful way of extracting elements from a vector is by indexing the vector using logical vectors. Here is how we can get the third and fourth elements of the vector:

```{r}
offer[c(F, T, T, F, F)]
```

Of course, we could compute the logical vector above using

```{r}
offer > 500
```

Combining those, we can go

```{r}
offer[offer > 500]
```

Note what we did: we extracted the elements that are larger than 500.


## Operating on logical values

Suppose we wanted something fancier: extracting all elements between 400 and 550. In other words, suppose we want the elements that are both larger than 400 and smaller than 550. To achieve this, we would want to combine the conditions "larger than 400" and "smaller than 550".

We can do this using logical operators

    AND:    a & b. TRUE only if a is TRUE and b is TRUE. FALSE otherwise
    OR:     a | b. TRUE if at least one of a or b is TRUE, FALSE otherwise
    NOT:    !a. TRUE if a is FALSE, FALSE if a is TRUE

Some examples:
 

```{r}
pie <- TRUE
icecream <- FALSE
pie | icecream
```

```{r}
pie <- FALSE
icecream <- FALSE
pie | icecream
```


```{r}
pie <- TRUE
icecream <- FALSE
pie & icecream
```

```{r}
pie <- TRUE
icecream <- TRUE
pie | icecream
```

Note: this is not quite how it works in English. If I say I will have pie or icecream, and then have both, that means what I said wasn't true. But for R, the expression `pie | icecream` is TRUE. Technically, `|` is called "inclusive OR" (as opposed to the "exclusive OR" we usually mean in English.)


```{r}
pie <- FALSE
icecream <- TRUE
pie | icecream
```

```{r}
pie <- FALSE
icecream <- FALSE
pie | icecream
```

```{r}
pie <- TRUE
!pie
```

So with all that said, we can go back to our original task:

```{r}
offer[offer > 400 & offer < 550]
```

Now, how could we get the **other* elements? Here is one way
```{r}
offer[!(offer > 400 & offer < 550)]
```

and here is another:
```{r}
offer[offer <= 400 | offer >= 550]
```

Why do both make sense? Why do we use `>=` and not `>` in the last one?


## Parallel vectors

Let's go back to `offer`. Actually, those were the average offers to various specialties of doctors:

```{r}
offer <- c(241, 590, 533, 425, 261)
spec <- c("family doc", "cardiologist", "orthopedic", "dermatologist", "psychiatrist")
```

So for example the offers to cardiologist were $590k per year in 2018. Suppose we want to automatically figure out which specialty makes the most money.

So, if we knew it were specialty number 2, we'd go `spec[2]`. But how do we figure out the `2`? 

Let's try another tack. We'd like to compute `spec[c(F, T, F, F, F)]`. Can we compute the logical vector? Here's an idea:

```{r}
offer == max(offer)
```

Combining those ideas, we'll get

```{r}
spec[offer == max(offer)]
```

So how do we get the 2? We can first generate the vector
```{r}
1:length(offer)  # generate c(1, 2, 3, ..., length(offer))
```

And now, we can simply go
```{r}
(1:length(offer))[offer == max(offer)]
```

The following is really unnecessarily complicated, but we could have
```{r}
spec[(1:length(offer))[offer == max(offer)]]
```


## Data frames

Data frames are R's way of storing tables (note that the salary data we had was also actually a table). Let's load a data frame (you must previously have successfully run `install.packages("babynames")`).

```{r}
library(babynames) #Load the data frame babynames into R
```

Here are the first several rows of the data frame

```{r}
head(babynames) # Display the first 5 rows of a data frame
```

We can access, for example, row 2 and column "year" of the table like so:

```{r}
babynames[2, "year"]
```

If we want to access all of row 2, we can omit the second part:

```{r}
babynames[2, ]
```

We can access rows 2 through 6 like so:

```{r}
babynames[2:6, ]
```

We can only take the columns `"n"` and `"year"`, like this:

```{r}
babynames[2:6, c("n", "year")]
```

Finally, if we want a particular column as a vector (rather than as a data frame), we can do the following (make sure to keep track of the quotes)

```{r}
babynames[5:20, ]$name
```


## Working with data frames

Let's now write code that finds the most common name in 1999

```{r}
babies.1999 <- babynames[babynames$year == 1999, ]
max.name.count <- max(babies.1999$n)
babies.1999[max.name.count == babies.1999$n, "name"]
```

And now, let's write a function to find the most common name in a given year, with a given sex

```{r}
MostCommonName <- function(babynames, year, sex){
  babies.match <- babynames[babynames$year == year & babynames$sex == sex, ]
  max.name.count <- max(babies.match$n)
  return(babies.match[max.name.count == babies.match$n, "name"])
}
```