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


## Rmd
Everything you see in the course website has been created with R relying on `.Rmd` files.
What you see here is an Rmd file which combines 

1. text with a simplified format
2. R chunks which can be executed independently

Rmd files can be "compiled" in various forms (html, doc, pdf, md) and are extremely handy.

## Pipes 
In almost all my code I rely on _pipes_ (`%>%`).
The pipe operator has been introduced in R (as part of the `magrittr` package) to make the code easier to read in presence of nested functions.

```{r}
library(magrittr)

## consider for example
a <- 10
b <- sqrt(log(a+2)) ## this is a trivial nested function ...

## with pipes I could write the same as 
b1 <- a %>% 
  add(2) %>%   ## here I'm adding 2 to a
  log(.) %>%   ### here I'm taking the log of a+2
  sqrt(.)

## the "dot" represent what is coming from the pipe

```

You can imagine the pipe operator just like a pipe, which connects two functions passing the output of the first to the input of the second.

This way of programming is particularly efficient when you want to do "data carpentry" on tabular data

## Tibbles 

Tibbles are the new version of R "data.frames". You can think to them as the analogous of Excel tables. Tibbles are the workhorse of the data analyst since almost all the data we will be digesting are organized as tables.

An interesting feature of tibbles is that they can contain columns of tables. The advantage of that will be clear during the demos. Just as an appetizer

```{r}
library(tidyverse)

## here I create a dummy table
my_first_tibble <- tibble(names = c("One","Two"),
                          counts = c(1,2))

my_first_tibble

```

and now I add a column of tables ...

```{r}
## this is a dummy matrix to be used just as an example
a_matrix <- matrix(1:4, nrow = 2)

## I'm adding here a 2 element column which combines twice the matrix
my_first_tibble$tables <- list(a_matrix,a_matrix)

## I'm doing that with the data carpentry machinery
my_first_tibble <- my_first_tibble %>% 
  add_column(other_tables = list(a_matrix,a_matrix))


my_first_tibble

```

Now you see that my table contains a column made of matrices

## `purrr` and cycles

In many cases you would like to apply some sort of function iteratively along a table. The standard way of doing this ion many programming languages is to use `for` loops. Unfortunately, for loops can be really slow in R. To work around this problem. base `r` provides a full set of *apply* functions (e.g. `apply`,`lapply`,`sapply`,`vapply` ...). Modern programming paradigms are making life easier using the `purrr` package

The `purrr` package (which is part of `tidyverse` ) allows you to recursively apply operations to data stored in tabular form.

BTW: Do you know how to write R functions???


Suppose, for example, that we want to calculate the determinant of the previous matrices

```{r}
## in R there is a specific function called "determinat" to do that
?determinant
```

If my data are organized in tabular form ...the determinant of the two matrices can be 
calculated in a very efficient and organized way as follows

```{r}
my_first_tibble <- 
  my_first_tibble %>% 
  mutate(determinant = map(tables, function(x) determinant(x))) %>% 
  mutate(determinant1 = map(tables, ~ determinant(.x)))

my_first_tibble
```
In words ...

1. take `my_first_tibble`
2. pipe it to a function called `mutate`, which creates a new column called _determinant_.
3. the content of determinant is created by `map`ing the R function `determinant` to the objects stored in the _tables_ column



```{r}
## this is the determinant of the first matrix
my_first_tibble$determinant[[1]]
```


## Homework
1. Create a tibble that contains 100 random sampling from a non normal distribution (I suggest to you uniform or a lognormal distribution).
2. Show that the means of the 100 samples shows a normal distribution regardless the shape of the distribution we are drawing from


To draw from different distributions:

* `runif` for uniform distribution
* `rlnorm` for the lognormal distribution


This is a brute force demonstration of the **central limit theorem**

```{r}
## We need a function to sample from the unigorm distribution

data_uniform <- runif(50)

```


```{r}
## here I'm creating the tibble which will contain the data
my_samplings <- tibble(id = 1:100)

## I want to add a column with the amplings

my_samplings <- my_samplings %>% 
  mutate(sampling = map(id, function(x) runif(50)))



```


Now we want to calculate the means of the independent samplings

```{r}
my_samplings <- my_samplings %>% 
  mutate(means = map(sampling, function(x) mean(x)))
```


Let's now look to the distribution of the means ...


```{r}
hist(unlist(my_samplings$means))
```

Here we are seeing that even if the samplings are coming from a uniform distribution, their means are normally distributed


As you may have noticed it was necessary to unlist the output of map ... thius is necessary because map will produce a list  ...

To make this step more straightforward, in `purrr` there is a `map_dbl` function which will output a number for each row


```{r}
my_samplings <- my_samplings %>% 
  mutate(means_1 = map_dbl(sampling, function(x) mean(x)))
```


With this you could also use directly ggplot


```{r}
my_samplings %>% 
  ggplot() + 
  geom_histogram(aes(x = means_1), fill= "darkred", col  ="white") + 
  theme_bw()
```






