---
title: "TP `R` 2: Statistiques descriptives et graphiques de base"
header-includes:
  - \usepackage[french]{babel}
subtitle: "Cours de Programmation"
author: "Vitorio Perduca, Master 1 Mathématiques et Applications"
date: "UFR Math-Info, Université Paris Descartes, septembre 2020"
output:
  pdf_document:
    toc: true
    toc_depth: 2
---


# 1. Données utilisées 

On illustrera les fonctions de base en utilisant le jeu de données `mtcars` disponible dans `R`. Pour une description de ces données, consulter l'aide `?mtcars`. On peut avoir une idée de la classe et du contenu de `mtcars` à l'aide de `str()`:

```{r}
str(mtcars)
```

La variable `cyl` représente le nombre de cylindres avec trois modalités possibles (4,6 ou 8), il est donc naturel de la convertir en facteur: 

```{r}
mtcars$cyl.factor <- as.factor(mtcars$cyl)
attach(mtcars)
```


# 2. Analyse univariée
## 2.1 Variables quantitatives

Pour une variable quantitative, les statistiques de base qu'on peut calculer sont le minimum, le maximum, la moyenne, la variance et l'écart type, la médiane et les autres quantiles (on rappelle que le quantile d'ordre $p$ est la valeur $q$ t.q. $p$ est la fraction des valeurs observées inférieures à $q$). 

```{r}
min(mpg)
max(mpg)
range(mpg)
mean(mpg)
var(mpg)
sd(mpg)
median(mpg)
quantile(mpg)
quantile(mpg, probs = 0.99) # pour le percentile d'ordre 99
quantile(mpg, probs = c(0.01, 0.1, 0.9, 0.99))
```

Si il y a des données manquantes, on les exclut du calcul de la statistique à l'aide de l'option `na.rm=TRUE`. 

La fonction générique `summary()` permet de décrire rapidement la distribution d'un échantillon et est complémentaire à la boîte à moustache:
```{r}
summary(mpg)
boxplot(mpg)
```

On rappelle que dans un boxplot

- la hauteur (ou largeur si on choisit l'option `horizontal=TRUE`) est définie par le premier et troisième quartile $q_1$ et $q_3$
- le trait horizontal (ou vertical) correspond à la médiane $m=q_2$
- la moustache en bas (ou à gauche) part de $q_1$ et va jusqu’au minimum de l’échantillon s’il n’y a pas de points extrêmes à gauche, c'est à dire des valeurs inférieures à $q_1-1.5\times(q_3-q_1)$. S’il y a de tels points, la moustache s’arrête en $q_1-1.5\times(q_3-q_1)$ et on les place au-dessous (à gauche) de celle-ci.
- la moustache en haut (ou à droite) part de $q_3$ et va jusqu'au maximum de l'échantillon s'il n'y a pas de poins extrêmes à droite, c'est à dire des valeurs supérieurs à $q_3+1.5\times(q_3-q_1)$. S’il y a de tels points, la moustache s’arrête en $q_3+1.5\times(q_3-q_1)$ et on les place au-dessus (à droite) de celle-ci.

L'autre outil graphique pour représenter la distribution d'une variable quantitative est l’histogramme:
```{r}
hist(mpg)
hist(mtcars$mpg, breaks = 20) # si on veut 20+1 intervalles 
hist(mtcars$mpg, breaks = c(10, 15, 18, 20, 22, 25, 35)) 
# on spécifie à la main les points qui définissent les intervalles 
```

On peut aussi comparer la distribution de l'échantillon avec la distribution théorique d'une loi normale centrée et réduite à l'aide du QQ-plot:
```{r}
qqnorm(mpg)
qqline(mpg) # la droite sample quantiles = theoretical quantiles
```

On peut comparer le QQ-plot précedant à celui de l'échantillon _centré et réduit_:

```{r, eval=FALSE}
mpg.stand <- (mpg-mean(mpg))/sd(mpg) # mpg centré et réduit
qqnorm(mpg.stand); qqline(mpg.stand)
```

Bien évidemment la distribution des quantiles ne changes pas:

```{r, eval=FALSE}
hist(quantile(mpg))
hist(quantile(mpg.stand))
```


## 2.2 Variables qualititatives

Les fonctions `summary()` et `table()` appliquées à un facteur (ou à un vecteur de caractères) comptent les occurrences des différents niveaux. 

```{r}
summary(cyl.factor)
table(cyl.factor)
```

Pour obtenir les proportions:
```{r}
prop.table(table(cyl.factor)) 
```

En présence de valeurs manquantes, `summary()` compte aussi les `NA`:
```{r}
x <- as.factor(c('a','a','b','c',NA,'c'))
summary(x)
table(x)
prop.table(table(x)) # les effectifs sont divisés par le nb total des valeurs non-manquantes
prop.table(summary(x)) # les effectifs sont divisés par le nb total des valeurs 
```

On utilisera un graphiques à barres ou un camembert (déconseillé):

```{r}
barplot(table(cyl.factor))
pie(summary(cyl.factor))
```
\newpage


# 3. Analyse bivariée
## 3.1 Variable quantitative vs variable quantitative

On considère deux variables quantitatives mesurées sur les mêmes individus.

La covariance de deux variable quantitatives mesure les écarts conjoints par rapport à leurs moyennes respectives. La coefficient de corrélation linéaire de Pearson $\rho$ mesure l'intensité de dépendance linéaire entre deux variables quantitatives. $\rho$ appartient à $[-1,1]$: il vaut $+1$ ($-1$) si il y a une dépendance linéaire positive (négative) et $0$ si il n'y a pas de dépendance linéaire.

```{r}
cov(mpg, wt)
cor(mpg, wt)
# cov(mpg, wt)/sd(mpg)/sd(wt) # essayer
```

La corrélation de Spearman mesure la corrélation linéaire entre les _rangs_ des valeurs de deux variables:

```{r}
cor(mpg, wt, method='spearman')
```

Pour représenter graphiquement deux variables quantitatives on utilisera un nuage de point, ou _scatter plot:_
```{r}
plot(x=wt, y=mpg) # x,y = coordonnées des points. 
# Alternative: plot(wt ~ mpg) où le ~ indique "wt en fonction de mpg" 
```

Pour trouver la droite des moindres carrés (modèle linéaire simple) et l'ajouter aux données:
```{r}
m <- lm(mpg ~ wt)
summary(m)
# essayer:
# pente <- sum((wt-mean(wt))*(mpg-mean(mpg)))/sum((wt-mean(wt))^2) 
# intercept <- mean(mpg) - pente * mean(wt)
plot(mpg ~ wt)
abline(m, col = "red")
```






## 3.2 Variable qualitative vs variable qualitative

On considère deux variables qualitatives mesurées sur les mêmes individus.

On fait des tables de contingences et on calcule les fréquences totales et marginales (en lignes et en colonnes):

```{r}
t <- table(cyl,am) 
# cyl et am sont des vécteurs numériques, 
# mais pour construire la table de contingence 
# table() compte leurs modalités.
print(t)
prop.table(t) # P(cyl,am)
prop.table(t, margin = 1) # P(am | cyl=4), P(am | cyl=6), P(am | cyl=8)
prop.table(t, margin = 2) # P(cyl | am=0), P(cyl | am=1)
```

Le graphique correspondant est le _mosaic plot_:
```{r}
par(mfrow=c(1,2)) # pour mettre deux graphiques côte à côte
mosaicplot(table(cyl,am)) # P(am | cyl=4), P(am | cyl=6), P(am | cyl=8)
mosaicplot(table(am,cyl)) # P(cyl | am=0), P(cyl | am=1)
```

## 3.3 Variable quantitative vs variable qualitative

Pour calculer une fonction `f` sur les valeurs d'une variable `y` pour chaque niveau d'un facteur `x` on utilise `tapply(X=y, INDEX=x, FUN=f)`. Cela est très utile quand on veut calculer les statistiques d'une variable quantitative `y` regroupées selon les niveaux d'une variable qualitative `x`:

```{r}
tapply(mtcars$mpg, mtcars$cyl, mean)
tapply(mtcars$mpg, mtcars$cyl, summary)
```

Graphiquement, on peut faire des boxplot de la variable quantitative en fonction de la variable qualitative:
```{r}
boxplot(mpg ~ cyl, data = mtcars)
```

\newpage


# 4. Détails sue les graphiques de base
## 4.1 Constructions de base et scatterplots

En `R` les graphiques sont crées par étapes: on crée un _plot_ et ensuite on ajoute des lignes, des points, une légende... Nous avons déjà vu comment ajouter une droite à un nuage de points, pour compléter le graphique nous pouvons spécifier un titre, changer les étiquettes aux axes, et ajouter une légende. 

```{r}
plot(wt, mpg, 
     main='Poids et consommation des voitures',
     xlab='poids',ylab='consommation') # xlab=label axe x
abline(h=mean(mpg),col=2,lty=2) # h=droite horizontale, col=couleur, lty=type de ligne
legend(x='topright',lty=2,col=2,legend='consommationne moyenne') 
# x=emplacement légende
```

Nous pouvons aussi ajouter une troisième dimension en coloriant les points selon une condition:

```{r}
plot(wt , mpg, 
     pch=19, # pch=type de point
     col=(mpg>=mean(mpg))+1 # 1=noir, 2=rouge
     )
abline(h=mean(mpg),col=2,lty=2) # h=droite horizontale, col=couleur, lty=type de ligne
legend(x='topright', 
       pch=19,
       col=2:1,
       legend=c('cons >= moyenne','cons < moyenne'), # legend=vecteur avec les labels
       bty='n' #pas de cadre autour de la légende
       )
```

En général, `abline(a,b)` permet d'ajouter à un plot existant une droite d'intercept `a` et pente `b`. Par exemple, une façon alternative d'ajouter la droite de régression est la suivante:
```{r, eval=FALSE}
intercept=coef(m)[1]
pente=coef(m)[2]
plot(wt , mpg, main='Droite des moindres carrés')
abline(a=intercept, b=pente) # abline() pour ajouter une droite
abline(lowess(wt,mpg))
```

Pour ajouter une ligne quelconque (pas nécessairement une droite) on utilise la fonction `lines()`. Par exemple, pour ajouter la courbe de lissage _lowess_ (locally-weighted polynomial regression):
```{r}
plot(wt, mpg, main='Courbe de lissage')
lines(lowess(mpg~wt), # lines(): pour ajouter une courbe
      col='blue', # même chose que col=4
      lwd=2) # lwd=epaisseur ligne
```

On peut ajouter de nouveaux points à l'aide de `points()`:
```{r}
plot(wt , mpg, main='Courbes de lissage')
lines(lowess(mpg~wt), col='blue', lwd=2)
outliers=cbind(c(4.5,4.6,5),c(26,26,30))
points(outliers,pch=2) # pch=2 pour des triangles
lines(lowess(c(wt,outliers[,1]),
             c(mpg,outliers[,2])
             ),
      col=2,lwd=2)
legend(x='bottomleft',col=c(4,2),lwd=2,legend=c('sans outliers','avec outliers'),bty='n')
```

On peut contrôler le range des axes à l'aide de `xlim()`et `ylim()`:

```{r}
plot(wt,mpg, main='Mêmes données avec differente échelle',
     xlim=c(0,25),
     ylim=c(0,100))
```
\newpage

## 4.2 Line graphs

La fonction `lines()` ajoute une ligne à un graphique existant et ne peut pas être utilisée pour créer un nouveau graphique. Pour connecter une ligne reliant les éléments successifs d'un vecteur on utilisera plutôt `plot(x=vecteur,type=l)`:

```{r}
mydata=cos(2*pi/12*(1:36)) + rnorm(36,0,.2) # simulation des données
plot(mydata,type='l',main='type=l')
```

Le paramètre `type` permet de relier (ou pas) les points de façons différentes:

```{r}
par(mfrow=c(2,2)) # expliqué dans la section suivante
plot(mydata,type='p',main='type=p') # défault
plot(mydata,type='o',main='type=o')
plot(1:10,type='S',main='type=S') # escalier 1
plot(1:10,type='s',main='type=s') # escalier 2
```

Avec `plot='h'` on obtient un graphiques à barres:

```{r}
plot(1:10,type='h',main='type=h')
```
\newpage

## 4.3 Paramètres graphiques

Nous avons déjà vu qu'il est possible de contrôler certains éléments graphiques à l'aide de paramètres:

Élément|Paramètre
-------|---------
point  | `pch`
Graphique de type ligne  | `type`
couleur| `col`
ligne  | `lty`, `lwd`
étiquette axes | `xlab`,`ylab`
dimensions axes | `xlim`,`ylim`
dimension labels | `cex`
orientation labels axes | `las`

Consulter `?par` pour une description des valeurs que ces paramètres peuvent prendre.

Pour imposer des paramètres à la totalité des graphiques produits au cours d'une session on utilisera la fonction `par()`. `par()` est souvent utilisée pour visualiser deux ou plusieurs plot dans la même fenêtre avec le paramètre `mfrow=c(l,c)`. Dans ce cas les graphiques sont visualisés dans une grille avec `l` lignes et `c` colonnes: 

```{r}
# opar = par() # pour pouvoir reinitialiser avec les paramètres initiaux
par(mfrow=c(1,2))
plot(wt,mpg,main='Poids, consommation')
boxplot(hp,main='Puissance')
```

Les changements sont implémentés jusqu'à quand la session est fermée, ou le moteur graphique est réinitialisé par `dev.off()` ou en cliquant sur le balai `Clear all plots` dans `RStudio`. 

`par()` est aussi utilisée pour changer la dimension des marges. Cela est parfois utile quand les labels sur les axes ne rentrent pas dans la fenêtre, comme dans cet exemple:

```{r}
mydata=as.factor(sample(x=c('Paris','Londres','Bruxelles','Washington'),
                        replace = T,
                        prob=c(.1,.5,.2,.1),
                        size=100)) # simulation d'une variable qualitative
barplot(summary(mydata),
        width=.1,
        horiz=T,
        las=2)
```

On modifie le paramètre qui règle la marge à gauche:

```{r}
par(mar=c(5, 6, 4, 2) + 0.1) # la deuxième composante de mar donne la marge à gauche 
# Default est c(5, 4, 4, 2) + 0.1 
barplot(summary(mydata),
        width=.1,
        horiz=T,
        las=2)
```
\newpage

## 4.4 Histogrammes

Par défaut, `hist()` affiche l'histogramme avec les comptages, ce qui correspond au paramètre `freq=TRUE` (en anglais _frequency_ indique les occurrences). Pour afficher l'histogramme avec la _densité_ on utilisera `freq=FALSE`. Dans ce cas, l'aire de chaque rectangle sera égale à la proportion d'observations dans la classe correspondante (de façon à que l'aire totale de tous les rectangles soit un).


```{r}
par(mfrow=c(1,2))
hist(mpg) # freq=TRUE
hist(mpg,freq=FALSE)
```
     
Pour superposer la courbe d'une densité donnée:
```{r}
mydata=rnorm(1000,0,1) # simulation de 1000 observations N(0,1)
hist(mydata,freq=F,main='Histogramme et densité théorique')
curve(dnorm, # la fonction de densité de N(0,1)
      from=-5,to=5, # le range
      add=TRUE) # parce qu'on veut ajouter la densité de N(0,1) à l'histogramme
```

Plutôt que de visualiser l'histogramme des données on peut visualiser la densité estimée par noyau:

```{r}
hist(mpg,freq=F,main='Histogramme et densité estimée')
lines(density(mpg),col=2)
```
\newpage

# 5. Exercices

1. On travaille sur les données démographiques `midwest` du package `ggplot2` (un package graphique avancé). Consulter l'aide pour la description des variables. Reproduire les graphiques suivants en utilisant les fonctions graphiques de base

```{r,echo=FALSE, warning=FALSE, message=FALSE}
library(ggplot2)

par(mfrow=c(1,2))
plot(midwest$area,midwest$poptotal,
     pch=19,
     xlab='Surface',ylab='Population',
     col=midwest$inmetro+1, 
     # inmetro=0=rural donc rural=0+1=noir
     # inmetro=1=urbain donc urbain=1+1=rouge
     main='Contées américaines'
     )
legend(x='topleft',pch=19,col=1:2,legend=c('Rural','Urbain'),box.lty=0)

plot(midwest$area,midwest$poptotal,
     pch=as.numeric(as.factor(midwest$state)),
     col=midwest$inmetro+1,
     xlab='Surface', ylab='Population',
     main='Contées américaines'
     )
legend(x='topleft',pch=c(1:5,1,1),
       col=c(rep(1,5),1:2),
       legend=c(levels(as.factor(midwest$state)),'Rural','Urbain'),
       box.lty=0)
```

2. On travaille sur le jeu de données `adult` disponible sur le site: [archive.ics.uci.edu/ml/datasets/Adult](https://archive.ics.uci.edu/ml/datasets/Adult). Il y a 14 colonnes dans cette table. Vous devez commencer par importer les données dans `R` (fichier `adult.data`). Pour les noms des variables, regarder dans le fichier `adult.names`. Répondre aux questions suivantes en rédigeant un rapport `R Markdown`.
    a. Décrire chaque variable de manière appropriée, selon le type de la variable.
    b. Décrire le lien entre les variables `age` et `class`.
Il existe plusieurs moyens de représenter chaque lien ne pas hésiter à en essayer plusieurs pour trouver la plus représentative.


