# 2.1.2 Functions {#chap:func}

## Learning Objectives

In R, everything that happens is a function call. As a first step, you should know how to:

- Use naming and positional matching to provide arguments, and
- Predict what the output of a function should look like, given the input.
- Operators are short-cuts for functions.

## Introduction

There are three predominant programming paradigms found in R: _functional_, _object-oriented_ and _reactive._ In this part of the Data Science Immersive course, we'll introduce you to the first two. We'll get to reactive programming when we introduce how to build interactive web apps for your data science projects later on.

In the context of functional programming, _everything that happens is a function call_. We'll get deep into objects in the next section. Here, we need to know some very basic things, like how to make objects and do math, but our focus is on functions.

## Arithmetic Operators

R is basically a simple, yet very powerful, calculator. which means it can handle all the usual _arithmetic operators_:

Table: (\#tab:Arithmetic-operators) Arithmetic operators.^[In addition to _arithmetic operators_ we will also encounter _relational operators_ (p. \@ref(sec:relational_operators)), _logical operators_ (p. \@ref(sec:logical_operators)) and special characters used in _regular expressions_ (p. \@ref(cha:RegEx)).]

| Operator            | Description                         |
|---------------------|-------------------------------------|
| `+`                 | Addition                            |
| `-`                 | Subtraction                         |
| `*`                 | Multiplication                      |
| `/`                 | Division                            |
| `^` or `**`         | Exponentiation                      |
| `%/%`               | Integer division - `5%/%2` is `2`   |
| `%%`                | Modulus/remainder - `5%%2` is `1`   |
| `()`                | Set order of operations             |

Consider the following examples. Use R's text editor to enter the following commands:

```{r results = 'hold'}
34 + 6 # Addition
34 / 6 # Division
34 %/% 6 # Integer division
34 %% 6 # Remainder
34^6 # Exponentiation

```

Don't forget your order of operations! BEDMAS = Brackets, exponents, division, multiplication, addition, subtraction:

```{r echo = FALSE}

options(digits = 3)
```

```{r results = 'hold'}
# These are different:
2 - 3 / 4
(2 - 3) / 4

```

```{r echo = FALSE}
options(digits = 2)
```


Now, assign the numbers 34 and 6 to objects `n` and `p`, respectively:

```{r results = 'hold'}
n <- 34 # Assign the value of 34 to n
p <- 6 # Assign the value of 6 to p
```

The whole point is that our objects, `n` and `p`, are place-holders _for_ -- and can be used in place _of_ -- the values.^[We already saw this in \@ref(logExample) when we assigned the result of `log2(8)` to the object `n`. What happens when we now assign the number `34` to `n`?]

```{r results='hold'}
n+p # 34 + 6
n/p # Division
n%/%p # 34 %/% 6
n%%p # 34 %% 6
n^p # 34^6
```

We'll return to objects in great detail in the next chapter, for now, let's dig into functions.

## What are Functions?

Functions are commands^[Functions are either built-in, provided by extension packages, or user-defined.] that accept zero or more user-specified arguments. Typically, functions follow the generic form

```
function_name(argument_1 = , ... )
```

where `function_name` is the function's name and `argument_1 =` specifies the first argument to be passed to the function. A function may have many arguments, but as long as they are given in order they don't need to be explicitly named.^[Omitting the argument name is common for functions with only a few arguments or for specifying the first few arguments of complex functions. However, it is useful to specify argument names until you become more experienced in writing R scripts.]

We already saw several functions, so let's review what we know. First we saw that there are some convenience functions

```{r eval = FALSE}
log2(8)
```

They basically provide an easier way of writing the full function:

```{r eval = FALSE}
log(8, base = 2)
```

Here, the first argument (`8`) is assigned via positional matching and the second (`base = 2`) is explicitly named. This combination is _very_ typical, but we often only use positional matching for simple functions.

```{r eval = FALSE}
log(8, 2)
```

OK, so what do you think about this?

```{r eval = FALSE}
log(2, x = 8)
```

It's a combination of positional matching and naming, and the result is the same, but it's really confusing! Don't do that! Try to keep your functions straight-forward. Table \@ref(#tab:first-functions) list some very common functions

Table: (\#tab:first-functions) Examples of some simple and frequently used functions for creating sequences.)

| Function | Description                  |
|----------|------------------------------|
| `c()`    | Combine arguments            |
| `seq()`  | Create a sequence of numbers |
| `rep()`  | Create a repetitive sequence |

For^[We'll see in the next chapter that this is a vector.] example, `c()` is a frequently used function that _combines_ values into a single object.


```{r}
xx <- c(3, 8, 9, 23)
xx
myNames <- c("healthy","tissue","quantity")
myNames

```

^[R recognizes words in quotation marks as a character string, and not the name of an object.]

`seq()` is convenient for producing a _sequence_ of numbers:

```{r}
foo1 <- seq(from=1,to=100,by=7)
foo1
```

But recall that we can just leave out the names, since `seq()` is common and straight-forward.

```{r}
seq(1,100,7) # Using positional matching

```

Things get interesting when objects are used as arguments:


```{r}
foo2 <- seq(1,n,p)
foo2

```

## The `:` operator {#ref:colon}

If we want to generate a regular integer sequence, we can use `:`, the _colon operator_ as a short-cut:

```{r}
1:10 # is short-hand for...
seq(from=1,to=10,by=1)

```


## Descriptive statistics

Table: (\#tab:desstatsfunctions) Frequently used functions in descriptive statistics.

| Function                   | Description                  |
|----------------------------|------------------------------|
| `length()`                 | Get the length of a vector   |
| `mean()`                   | Mean (average), $bar(x)$     |
| `names(sort(-table()))[1]` | Mode (most frequent value)   |
| `median()`                 | Median (middle value)        |
| `var()`                    | Variance, $s^2$              |
| `sd()`                     | Standard deviation, $s^2$    |
| `IQR()`                    | The inter-quartile range     |
| `max()`                    | Maximium number              |
| `min()`                    | Minimum number               |
| `range()`                  | Range - In R, the min \& max |


^[Note that the `::` operator tells us that the `std.error()` function is in the `plotrix` package. See \@ref(heading:packages) for details on how to use packages.]

Table \@ref(tab:desstatsfunctions) lists some common functions for descriptive statistics. We can calculate some descriptive statistics on `foo1` and `foo2`:

```{r}
length(foo1) # the n
mean(foo1) # the mean
```

With the exception of `range()`,^[In R, range() is a bit of an anomaly, since we typically think of the range as a single value, i.e. the difference between the max and min. Instead, R returns two values, i.e. the min and max.] all the functions in table \@ref(tab:des-stats-functions) return a single value. Notice that in this situation, we can describe mathematical functions in two fundamental ways:

**Aggregation** functions _summarise_ data and return (typically) a single value.

**Transformation** functions _mutate_ each individual data point in exactly the same way. The number of output values equal the number of input values.

We just saw some aggregation functions, but we've already seen a transformation function!

```{r}
foo2
log2(foo2)

```

What are some other examples of transformation functions?

```{r}
# The square root of foo1
sqrt(foo2)

```

Of course we can combine aggregation and transformation functions. For example, when calculating a Z-score normalisation ($z = \frac {x_i - \bar{x}}{s}$):

```{r}
(foo2 - mean(foo2)) / sd(foo2) # Remember BEDMAS!
```

What we just saw is a profound and important point in R. What happened?

Following the order of operations: the mean of `foo1` was calculated (an aggregation function), then subtracted from each _individual_ value in the whole `foo1` series (a transformation function). Then the same thing happened with the division of the standard deviation.

```{exercise, name="Predict output"}
Given `foo2`, can you predict the outcome of the following commands? Are they transformation or aggregation functions?
```

```
> foo2 + 100
```

```
> foo2 + foo2
```

```
> sum(foo2) + foo2
```

```
> 1:3 + foo2
```

This is an interesting, important and very convenient concept, so let's make sure you understand what's going on here.

```{exercise, name="Calculate results"}
Use the linear equation from the previous exercises to calculate $y=1.12x-0.4$ for `xx`.
```

So far so good. If you understand the premise, you should have gotten `r 1.12*xx-0.4` from a single command.

```{exercise, name="Multiple iterations"}
Continuing from the previous exercise, how would you calculate the result of our equation if we had more than one slope? e.g.
```

```
> m2 <- c(0, 1.12)
```

```{r}
m2 <- c(0, 1.12)
m <- 1.12
b <- -0.4
```

So this is a bit trickier, because of vector recycling! Of course there are way of dealing with this, which brings us into the topic of _creating_ functions of our own.
