forked from MTES-MCT/parcours_r_socle_introduction
-
Notifications
You must be signed in to change notification settings - Fork 0
/
10-rbase.Rmd
281 lines (200 loc) · 10.7 KB
/
10-rbase.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# Aller plus loin avec les objets, crochets et la programmation fonctionnelle
Ce qui a été présenté dans ce module repose sur les fonctions du package `tidyverse`. Cette approche tend à se généraliser depuis quelques années, mais quand on cherche la réponse à un problème sur Internet, on trouve d'autres façons de programmer en R, qui font appel aux fonctions du package `base` et non du `tidyverse`
$\Rightarrow$ Cette partie donne quelques clés de compréhension.
## Les objets dans R
Rappel : en informatique, un objet est défini par : ses *attributs* et ses *méthodes* (fonctions). Dans l'exemple du jeu d'échec, chaque pièce peut être vue comme un objet :
- sa position sur le plateau constitue ses attributs
- sa façon de se déplacer peut être vue comme une fonction qui ne s'applique qu'à ce type de pièce, donc une méthode
R est un langage orienté objet ; ces objets permettent de structurer les données selon leurs caractéristiques $\Rightarrow$ on retrouve les données dans les attributs. Les méthodes sont en général transparentes pour l'utilisateur (cf. utilisation des fonctions `summary`, `plot`...). Les objets les plus courants sont les suivants :
- **Vecteurs** : suite unidimensionnelle de **valeurs** ayant le même type.
- **Facteurs** : vecteur qui prend un nombre limité de modalités (exemple : sexe). Il est défini par les niveaux (`levels`) et les libellés associés (`labels`).
- **Matrice** et **arrays** : suites multidimensionnelles de **valeurs** (matrices=dimension 2 ; array=dimension n).
- **Liste** : ensemble d'**objets** différents. On peut stocker un vecteur alphanumérique + une matrice numérique dans une liste.
- **Tableaux** (`data.frame`) : Objet qui ressemble le plus aux tables Excel, SAS ou SPSS... : description d'individus statistiques (observations, en ligne) par des caractéristiques (variables, en colonnes).
* **Fonctions** : Objets particuliers qui donnent un *résultat* à partir de paramètres en entrée.
- **Autres objets** : Il existe un très grand nombre d'objets *ad hoc* dans R. Par exemple
+ *ts* (time serie) pour les séries temporelles,
+ *lm* (linear model) qui contient tous les résultats d'une régression linéraire...
+ des graphiques
+ On peut même en définir de nouveaux soi-même !
La fonction `c` permet de lister simplement les valeurs que l'on veut stocker dans l'objet ; la fonction `seq` génére une suite incrémentée. Il existe aussi la fonction `rep` qui réplique n fois la même valeur.
### Créer des vecteurs
```{r}
v1 <- seq(1 : 10)
v2 <- c ("lundi", "mardi", "mercredi", "jeudi",
"vendredi", "samedi", "dimanche")
```
### Créer une matrice
```{r}
m <- matrix (v1, nrow = 10, ncol = 7)
l <- list (v1, v2, m)
```
### Visualiser ces objets et leurs attributs
Quelques fonctions simples : `print`, `View`, `names`, `colnames`, `rownames`, `typeof`, `str`, `dim`
```{r}
v1
print (v2)
typeof (v2) # Permet de visualiser le type
dim (m)
str (l) # Permet de visualiser les attributs
```
## Sélectionner des lignes et des colonnes
Il est aussi possible d'accéder aux éléments d’un dataframe à partir du numéro de ligne et de colonne, grâce aux crochets :
<center>![](images/DF2.png)</center>
- `base[1,3]` $\rightarrow$ <span style="color:red">valeur de la première ligne et de la troisième colonne </span>
- `base[2,]` $\rightarrow$ <span style="color:blue">toutes les variables pour la 2e observation</span>
- `base[,4]` $\rightarrow$ <span style="color:green">toutes les observations de la quatrième colonne </span>
- `base[,’V6’]` $\rightarrow$ <span style="color:cyan">toutes les observations de la variable V6</span>
- $\Rightarrow$ Utile pour sélectionner une partie d'une table : `base[1:4, c(3, 6)]`
## Créer une nouvelle fonction en R
La fonction est un objet comme les autres, qu'on crée avec l'opérateur d'affectation. Elle est définie par des paramètres et elle se termine par la fonction `return()`. On reprend l'exemple du calcul de l'IMC
```{r}
calcul_IMC <- function (poids, taille)
{
## La taille est exprimée en mètres
imc <- poids / taille ^ 2
return (imc)
}
calcul_IMC (poids = 80, taille = 1.89)
calcul_IMC (poids = 60, taille = 1.55)
```
## Les boucles conditionnelles
Les commandes `if` et `else` sont bien entendues utilisables. Le "then" n'existe pas : il est implicite après les accolades.
```{r}
diag_IMC <- function(poids,taille)
{
imc <- poids / taille ^ 2
if (imc < 18.5) {diag <- "maigre"}
else if (imc < 25) {diag <- "normal"}
else {diag <- "surpoids"}
return (diag)
}
diag_IMC (poids=60,taille=1.89)
diag_IMC (poids=80,taille=1.89)
diag_IMC (poids=80,taille=1.55)
```
## Les boucles
On peut utiliser les boucles classiques : `repeat`, `while`, `for` :
```{r}
for (pp in seq(from = 50, to = 100, by = 5))
{
print(paste ("Taille = 1,70m, poids =", pp, "Diagnotic :",
diag_IMC (poids = pp, taille = 1.70)))
}
```
## Exercices
### Vecteurs simples
- Créer trois vecteurs : un numérique, un caractère et un facteur. Vous pouvez vous aider des fonctions `c()`, `rnorm()` (génération d'une variable aléatoire selon une loi normale), `seq()` ou `rep()`
- Regrouper ces variables dans un dataframe, puis dans une liste. Dans les deux configurations, afficher la variable contenant les tailles (vtaille). Pour la liste, utiliser les [] et [[]].
```{r}
rm (list = ls ())
x <- c (1, 160, 2, 9, 60)
x1 <- c("Je", "programme", "en", "R") # Guillemets pour indiquer que c'est une variable textuelle
y <- seq (from = 1, to = 10, by = 1)
z <- rep (x = 1, times = 100)
x <- rnorm (n = 30)
# création de vecteurs avec la fonction c() = combine
v1 <- c( 3, 4, 12, 15, 32, 6, 1, 2, 3, 9)
# avec la fonction seq() = sequence, généralisation de la syntaxe ci-dessus
v2 <- seq(from = 1 , to = 15 , by = 1.5)
# syntaxe équivalente mais préférable car plus lisible :
v2b <- seq (from=1, to=15, by=1.5)
v3 <- 1:10
# avec la fonction rep() = répétition
v4 <- rep (x = 4, times = 10)
# ces commandes peuvent être combinées. Pratique pour créer des variables "facteur"
v5 <- rep (x = c(3, 4, 1.2, 8, 9), times = 2)
v6 <- rep (x = 1:5, times = 2)
# vecteurs de type texte ou factor
vtaille <- rep (x = c ("S", "L"), times = 5)
vtaille <- factor (vtaille)
# concaténation de vecteurs
gtaille <- paste("X", vtaille, sep = "")
gtaille <- factor (gtaille)
toutes_taille <- c (as.character (vtaille), as.character (gtaille))
toutes_taille <- as.factor (toutes_taille)
levels (toutes_taille)
```
### Dataframes et listes
```{r}
dataf <- data.frame (vtaille, v1, v2, v3, v4, v5, v6)
liste <- list (vtaille, v1, v2, v3, v4, v5, v6)
names(liste) <- c ("vtaille", "v1", "v2", "v3", "v4", "v5", "v6")
dataf$vtaille
liste$vtaille
rm (dataf, vtaille, v1, v2, v2b, v3, v4, v5, v6)
```
### Pour aller plus loin : matrices et arrays
Les matrices et les arrays permettent des calculs rapides et efficaces, et peuvent être très pratiques et optimisent le stockage des données. Ils demandent cependant plus de réflexion en amont quant à leur utilisation, mais . On accède aux éléments avec les [].
- Créer une matrice à 10 lignes et 10 colonnes remplie avec un tirage aléatoire selon une loi normale centrée réduit.
- Créer un hypercube avec la fonction `array()` avec 10 lignes, 5 colonnes et de profondeur 3, toujours avec un tirage aléatoire selon une loi normale
Un hypercube de trois dimensions peut être représenté comme suit :
![](images/grille.jpg){width=50%}
```{r}
mat <- matrix(rnorm(50), ncol = 5, nrow = 10)
arr <- array(rnorm(150),dim = c(10,5,3))
mat
arr
```
*Pourquoi s'embêter avec ça ?* Parce qu'on peut appliquer des fonctions facilement sur les lignes, colonnes et autres dimensions grâce à la fonction ```apply()```.
Exemple : résultats de validations croisées par bloc, simulations de loi selon différents paramètres. Et on calcule facilement des statistiques "marginales".
Par, exemple, sur une matrice, on peut calculer des statistiques par lignes :
```{r}
apply(mat, MARGIN = 1, FUN=mean)
```
Ou par colonnes :
```{r}
apply(mat, MARGIN = 2, FUN=mean)
```
Sur notre hypercube de type ```array```, on peut aussi calculer des stats sur ses différentes dimensions :
```{r}
apply (arr, MARGIN = 3, FUN=mean)
apply (arr, MARGIN = c(2,3), FUN = mean)
```
**Le coin du capitaine [ ]**![ ](images/CapHookImage.png){ width=10% }
Le crochet, c'est comme le capitaine du même nom : personne ne l'aime, mais sans lui, pas de Peter Pan, pas de Neverland ! Moralité, on s'en sert beacoup pour pimenter les codes ! On peut utiliser les crochets pour accéder aux éléments des matrices/arrays et dataframe/listes.
- Matrices et arrays
```{r}
mat [1,1]
mat [1,]
mat [,1]
arr [1,1,1]
arr [1,,]
arr [,,1]
```
- dataframes et listes :
Pour les dataframes, le fonctionnement est le même que pour les matrices. Pour les listes, une paire de crochet renvoie un résultat sous forme de liste, un double crochet renvoie le résultat sous sa forme naturelle (ex : vecteur ou matrice).
```{r}
str (liste [1])
str (liste [[1]])
liste["v6"]
liste[c("v6", "v5")]
```
>Dans la syntaxe `tidyverse`, on ne met pas (obligatoirement) de guillemets pour les noms de variable, alors qu'on le fait pour la version [ ].
### Inspection d'un objet : la régression
```{r,echo=FALSE}
library ("ggplot2")
reg <- lm (data = iris, formula = Sepal.Length ~ Petal.Length)
ggplot (data = iris, aes(x = Petal.Length, y = Sepal.Length)) +
geom_point () +
geom_smooth (method = "lm", se = FALSE) +
ggtitle ("Illustration de la régression linéaire simple")
```
La régression linéaire consiste à exprimer une variable Y en fonction d'une variable X dans une fonction linéaire. C'est à dire qu'on cherche a et b tels que : $$ Y = a \cdot X + b + \epsilon$$
où $\epsilon$ est le résidu de la régression. On utilise dans cet exemple la table des iris de Fisher, existant dans R base qu'il suffit d'appeler avec `data(iris)` (il existe d'autres dataframe inclus dans les packages et qui sont utilisés en exemple dans l'aide).
```{r}
data ("iris")
str (iris)
```
Faire la régression de la Sepal.Length sur Petal.length à l'aide de la fonction `lm()`
```{r}
lm (data = iris, formula = Sepal.Length ~ Petal.Length)
```
On a les paramètres a et b mais on aimerait en savoir plus... Au moins la qualité d'ajustement (le $R^2$ par exemple), et un graphique des résidus pour détecter une éventuelle structure. Pour cela, stocker le résultat dans un nouvel objet, et explorez-le avec les fonctions `str()`, `summary()` et `plot()`
```{r}
reg <- lm(data = iris, formula = Sepal.Length ~ Petal.Length)
str (reg)
summary (reg)
plot (reg)
```
Les **méthodes** summary, print et plot sont implémentées pour tous les objets en R, et on peut les utiliser pour avoir un premier aperçu de ce que l'on obtient avec la fonction.