```{r setup, include=FALSE, size="huge"}
library(knitr)
## Default parameters for displaying the slides
knitr::opts_chunk$set(
  echo = TRUE, 
  eval=TRUE, 
  fig.width = 7, 
  fig.height = 5, 
  fig.align = "center", 
  fig.path = "figures/",
  size = "tiny", 
  warning = FALSE, 
  results = TRUE, 
  message = FALSE, 
  comment = "")

dir.main <- "~/stat1"
dir.current <- file.path(dir.main, "practicals", "01_intro_R")
setwd(dir.current)

```


## But de ce tutoriel

Le but de ce tutoriel est de décuvrir les éléments fondamentaux du langage de statistiques ***R***. 

Nous aborderons les éléments suivants: 

- Manupulation de variables

    - Assignation d'une valeur à une variable
    - Opérations basiques sur des nombres
    - Structures de base: 
    
        - vecteurs, 
        - matrices
        - data.frames
        - listes

- Fonctions

- Graphiques

- Distributions de probabilités


## Utiliser ***R*** comme calculette

**Exemple:** une addition avec R.

```{r}
2 + 5
```

Le résultat affiché ($7$) est précédé d'un indice ($[1]$). Nous verrons ultérieurement l'utilisation de ces indices. 

## Assignation d'une valeur à une variable

En ***R***, la combinaison de lettres "trait d'union" et "plus petit que" (`<-`) indique qu'il faut assigner une valeur à une variable.

Ainsi, la commande suivante

```{r}
a <- 2
```

- crée une variable nommée $a$, 
- lui assigner la valeur $2$, 


Le résultat peut être affiché avec la fonction R `print()`. 

```{r}
print(a)
```

**Remarque : ** R permet également d'utiliser le symbole "égale" (`=`) pour effectuer une assignation. Cependant, nous préférons utiliser l'opérateur explicite `<-`, qui est également préconisé sur les [recommandations de style](https://google.github.io/styleguide/Rguide.html).

## Conventions de notation en R

Il existe plusieurs conventions possibles pour les noms de variables, de fonction, les opérateurs, etc. Chaque langage de programmation a ses propres standards et recommandations. Pour ce cours nous suivons les recommandations de **Google R style guide :**

<https://google.github.io/styleguide/Rguide.xml>

Cependant, pour les [identifiants de variables](https://google.github.io/styleguide/Rguide.xml#identifiers), la notation `variable.name` est traditionnelle mais pose problème aux personnes familières avec les langages orientés objet, et nous admettons donc la notation alternative en "dos de chameau" de type `variableName`. Attention, par convention les noms de variables commencent toujours par une minuscule. 

## Calculer avec des variables

- créer une variable nommée $b$ avec une valeur $5$, 
- calculer  $a + b$ et enregistrer le résultat dans une variable nommée $c$,
- imprimer le résultat. 

```{r}
b <- 5
c <- a + b
print(a)
print(b)
print(c)
```

## Assignation $\neq$ égalité

- remplacer la valeur de $a$ par $3$, 
- imprimer la valeur de $c$
- est-il toujours vrai que $c = a + b$ ? Pourquoi ?

```{r}
a <- 3 ## Change the value of a
print(a)
print(b)
print(c)

## Check whether c equals a + b
c == a + b
```

Note: **`==`** indique qu'on teste si deux variables ont le même contenu. Le résultat est une valeur logique (TRUE ou FALSE).

## Recalculer un résultat

Quand on change le contenu d'une variable $a$, une autre variable ($c$) préalablement calculées à partir de cette variable n'a aucune raison d'être recalculée si on ne le demande pas explicitement. 

**Exemple:** 

- remplacer la valeur de $a$ par $27$, 
- recalculer et imprimer la valeur de $c$
- tester l'égalité $c = a + b$

```{r}
a <- 27 ## Change the value of a
c <- a + b
print(c) ## Print the value of c

## Check whether c  equals a + b
c == a + b
```

## Vecteurs de valeurs

En  ***R***, la structure de données la plus simple est un **vecteur**. 

- Dans l'exemple précédent, la variable $a$ ne contenait qu'un seul nombre, mais en pratique elle était stockée dans un vecteur à une seule entrée. 

- La fonction `print()` affiche les indices en début de lignes, ce qui est utile quand on affiche des vecteurs avec un grand nombre d'entrées. 


**Exemple:** créer une variable nommée  ***troisNombres***, et l'initialiser avec un vecteur dont les valeurs sont ***27***, ***12*** et ***3000***.

**Trucs:**

- la fonction `c()` combine plusieurs valeurs en un vecteur.

```{r}
troisNombres <- c(27,12,3000)
print(troisNombres)
```


## Séries de nombres

La façon la plus simple de créer une série de nombre est d'utiliser le double point, qui génère toutes les valeurs entières entre deux limites. 

```{r}
x <- 0:30
print(x)
```

**Note: ** si l'impression des valeurs du vecteur dépasse la largeur de la console, R passe à la ligne et affiche en début de ligne  l'indice du premier élément. 

Un autre exemple: 


```{r}
print(58:157)
```


## Calculer avec des vecteurs


**R** permet de manipuler les vecteurs de façon extrêmement pratique. 
Une opération sur un vecteur s'applique automatiquement à tous ses éléments. 


```{r}
x <- 1:10 # Define a series from 1 to 10
print(x)
y <- x^2 # Compute the square of each number
print(y)
```


## Séquences de nombres

La fonction `seq()` permet de générer des séries de nombres séparés par un intervalle arbitraire. 

```{r}
seq(from=-1, to=1, by=0.1)
```

## Les variables peuvent contenir du texte

Les variables ne se limitent pas aux nombres: elles peuvent contenir du texte ("chaînes de caractères", "strings" en anglais).

Ici également, nous utilisons la fonction `c()` pour combiner plusieurs chaînes de caractères dans un vecteur. 

```{r}
# The # symbol allows to insert comments in R code

# Define  a vector named "whoami", and 
# containing two names
whoami <- c("Denis", "Siméon")
print(whoami) # Comment at the end of a line
```

## Concaténation de chaînes de caractèrs

La fonction `paste()` permet de concaténer les variables contenant du texte. 

```{r}
# To concatenate the elements of a vector in a single chain, use "collapse"
firstName <- paste(collapse = " ", whoami)
print(firstName)

# TO concatenate two vectors, use "sep"
lastName <- "Poisson"
print(paste(sep = " ", firstName, lastName))

## Concatenate 2 vectors with 3 values each
firstNames <- c("George", "Alfred", "Frédéric")
lastNames <- c("Sand",  "Musset", "Chopin")
fullNames <- paste(sep = " ", firstNames, lastNames)
print(fullNames)

```



Notez que la fonction `paste()` peut aussi s'utiliser pour concaténer toutes les valeurs d'un vecteur, mais ceci requiert de définir l'argument  `collapse` à la place de `sep`. 


```{r}
paste(fullNames, collapse = ", ")
```


## Fonctions graphiques

R comporte un grand nombre de fonctions permettant de dessiner des graphiques simples ou élaborés. Nous allons explorer ici les méthodes les plus simples. 

## Nuage de points (scatter plot)

```{r scatter_plot, fig.width=7, fig.height=5, fig.align="center"}
x <- seq(from = -10, to = 10, by = 0.1)
y <- x^2
plot(x,y)
```

## Courbe (line plot)


```{r line_plot, fig.width=7, fig.height=5, fig.align="center"}
x <- seq(from = -10, to = 10, by = 0.1)
y <- x^2
plot(x,y, type="l")
```


## Améliorer un dessin

**Exercice: ** lisez l'aide de la fonction `plot()` en tapant `help(plot)`, et explorez les paramètres afin d'améliorer le graphique. Consultez également l'aide de la fonction `par()` (paramètres graphiques). 


Vous pouvez par exemple ajouter les éléments suivants: 

- titre
- étiquettes des axes
- coloration de la courbe
- épaisseur de la courbe
- grille
- tracer une droite horizontale sur l'axe $X=0$
- tracer une droite verticale sur l'axe $Y=0$
- tout autre paramètre qui améliorera la lisibilité du résultat

La solution se trouve sur la diapo suivante (ne regardez pas !). 

## Solution

Exécutez le bloc de code-ci-dessous pour afficher le résultat. 

```{r line_plot_improved, fig.width=7, fig.height=5, fig.align="center", echo = TRUE, eval = FALSE}
x <- seq(from = -10, to = 10, by = 0.1)
y <- x^2
plot(x,y, 
     type="l", # Plot type
     main = "Parabole", # Main title
     xlab = "x", #X label
     ylab = "y = x^2", # Y label
     col = "blue", # Curve color
     lwd = 3, # Line width
     las = 1 # display axis labels horizontally 
     )
grid(lty = "dashed", col="gray") # Grid
abline(h = 0) # Horizontal line
abline(v = 0) # Vertical line

```


## Distributions de probabilités

**R** fournit 4 fonctions pour chacune des des distributions de probabilité classiques. 

Avant d'aller plus loin, lisez attentivement l'aide pour les fonctions associées à la distribution binomiale.

```{r binomial_help}
help("Binomial")

```

**Questions:** 

1. Quelle est la fonction R qui permet de calculer la fonction de masse de probabilité (également appelée "densité") ?
2. Quelle fonction R correspond à la fonction de répartition (également appelée "fonction de distribution") ?
2. A quoi sert la fonction *rbinom()* ?

## Graphe de la binomiale

**Exercice:** en supposant des nucléotides équiprobables et indépendants, dessiner la distribution de probabilité du nombre d'adénines pour un oligonucléotide de taille 30. 

- fonction de masse de la probabilité
- fonction de répartition

Dans les diapos suivantes, nous vous guidons pas à pas pour débuter l'exercice, et vous pourrez ensuite améliorer le résultat à vote guise. 

## Formule de la solution

Le nombre d'adénines peut prendre n'importe quelle valeur entre $0$ et $30$. On peut modéliser le problème comme un schéma de Bernoulli avec $n=30$ essais pouvant chacun résulter en un succès (une adénine) avec une probabilité $p=0.25$, ou un échec (tout autre nucléotide), avec une probabilité $q = 1-p = 0.75$. 

La probabilité d'observer exactement $x$ adénine vaut donc. 

$$P(X=x) = \binom{n}{x} p^x (1-p)^{n-x} = \frac{30!}{x!(30-x)!} \cdot 0.25^x \cdot 0.75^{n-x}$$
où $x$ peut prendre n'importe quelle valeur entre $0$ et $30$. 

## Calcul de la fonction de masse de probabilité

```{r binomial_PMF}
## Define all possible values for X
n <- 30
x <- 0:n
p <- 0.25

## Compute the binomial PMF
pmf <- dbinom(x = x, size = n, prob = p)
```

## Sous-ensemble des valeurs d'un vecteur

Nous pouvons sélectionner les 5 premières valeurs de la variable *pmf* (qui correspondent aux nombres de succès $x$ allant de $0$ à $4$) ...

```{r}
pmf[1:5]
```

... ou les 4 dernières valeurs ($x$ allant de $27$ à $30$ succès).

```{r}
pmf[(n-3):n]
```

## Restriction du nombre de décimales

La fonction `round()` arrondit un résultat à un nombre donné de décimales. 

```{r}
round(pmf, digit=3)
```

Pour des distributions de probabilités, on descend assez facilement à des valeurs très faibles, dont on désire connaître l'ordre de grandeur tout en affichant un nombre raisonnable de chiffres significatifs (ceux qui suivent la première décimale non nulle). Pour cela, il est plus pratique d'utiliser la fonction `signif()`.

```{r}
signif(pmf, digit=3)
```


## Dessin de la distribution binomiale


```{r dbinom_plot, fig.width=7, fig.height=4, fig.align="center"}
n <- 30; x <- 0:n   # Define the X values from 0 to 14
y <- dbinom(x = x, size = n, prob = 0.25) # Poisson density
plot(x,y) # Check the result
```

Ce premier dessin n'est pas très élégant. Les points ne se détachent pas très bien du fond. Nous allons améliorer ce dessin.  

## Exercice 1 : améliorer le dessin de la binomiale

Utilisez les différentes option de la fonction `plot()` pour mieux mettre en évidence la forme de la distribution (résultat attendu sur la diapo suivante). 

- Commencez par choisir un type de points  (option `type`) qui donne l'impression de la hauteur de la probabilité (valeur $Y$) correspondant à chaque point de l'axe $X$.

- Ajoutez un titre (option `main`) et adaptez les légendes aux axes (options `xlab`et `ylab`)

- Colorez le dessin (option `col`)

- Epaississez les traits (option `lwd`)

- Ajoutez une grille horizontale (fonction `grid()`)

- Assurez-vous que les étiquettes des axes soient toutes horizontales (option `las`).


## Résultat attendu

```{r dbinom_plot_improved, fig.width=7, fig.height=4, out.width="80%", fig.align="center", echo = FALSE}
n <- 30; x <- 0:n   # Define the X values from 0 to 14
y <- dbinom(x = x, size = n, prob = 0.25) # Poisson density
plot(x, y,
     main = "Binomial distribution",
     xlab = "X (Number of successes)",
     ylab = "P(X)",
     col = 'blue',
     lwd = 6,
     las = 1,
     type = "h")
grid(lty = "solid", col="gray")


```


## Exercice: série de courbes binomiales

Dessinez une série de courbes binomiales avec $n=30$ essais, et des valeurs de $p$ allant de $0.1$ à $0.9$ par pas de $0.1$. 

```{r binomial_series, fig.width = 12, fig.height = 6, out.width = "60%", echo = FALSE}
par(mfrow = c(3,3))
n <- 30  # Number of trials
x <- 0:n # Number of successes
for (p in seq(from = 0.1, to = 0.9, by = 0.1)) {
  plot(x, dbinom(x, prob = p, size = n),
       main = paste("p =", p),
       ylab = "P(X)",
       type = "h", lwd = 2, col = "blue"
       )
}

par(mfrow = c(1,1))

```


## Exercice: convergence de la binomiale vers une normale

```{r fig.width = 10, fig.height = 8, out.width="80%", echo = FALSE}
n <- 10
p <- 0.4

#' @title PLot a binomial disrtribution
#' @param size number of trials
#' @param prob probability of success at each trial
BinomPlot <- function(size, prob, ...) {
  x <- 0:size
  
  mean  <- prob * size
  binomVar <- size * prob * (1 - prob)
  binomSD <- sqrt(binomVar)
  plotXLim <- c(mean - 4 * binomSD, 
            mean + 4 * binomSD)

  y <- dbinom(x = x, size = size, prob = prob)
  plot(x, y, type="h", col = "gray", xlim = plotXLim, ...)

  
  abline(v=mean)
  
  abline(v = mean - binomSD, lty = "dashed", col = "blue")
  abline(v = mean + binomSD, lty = "dashed", col = "blue")
  
}



par(mfrow=c(2,3))
for (n in c(10, 100, 1000, 1000, 10000, 10000)) {
  BinomPlot(prob = 0.4, size = n)
  x <- 0:n
  
  ## Draw a normal curve above the binomial
  lines(x, dnorm(x, mean = p * n, sd = sqrt(p * (1 - p ) * n)), type = "l", col = "red")
}
par(mfrow=c(1,1))

```



## Avant de terminer : conservez la trace de votre session

La traçabilité et la reproductibilité des analyses constituent un enjeu essentiel en sciences. 
La fonction ***R***  `sessionInfo()` fournit un résumé des conditions d'une session de travail: version de R, système opérateur, bibliothèques de fonctions utilisées. 


```{r}
sessionInfo()
```

