-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtidy_data_dplyr.Rmd
296 lines (205 loc) · 13 KB
/
tidy_data_dplyr.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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# Revue détaillée : Tidy Data & dplyr {#tidy}
![](images/banners/banner_tidy_data_dplyr.png)
*Ce chapitre est à l'origine une contribution communautaire de [akshatapatel](https://github.com/akshatapatel){target="_blank"}*
*En cours de progression. Toute amélioration est la bienvenue. Si vous souhaitez participer rendez vous sur [contribuer au repo](contribute.html).*
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(MASS)
class(biopsy)
library(dplyr)
```
## Vue d'ensemble
Cet exemple présente certains travaux avec le jeu de données `biopsy` en utilisant les fonctions de `dplyr` pour obtenir un tidy dataset.
### Les packages
* [`dplyr`](https://www.rdocumentation.org/packages/dplyr){target="_blank"}
* [`MASS`](https://www.rdocumentation.org/packages/MASS/versions/7.3-51.1){target="_blank"}
* [`tidyr`](https://www.rdocumentation.org/packages/tidyr/versions/0.8.2){target="_blank"}
## Installer les packages
Écrivez le statements suivant dans le console:
* `install.packages('dplyr')`
* `install.packages('ggplot2')`
* `install.packages('tidyr')`
* `install.packages('MASS')`
**Remarque**: Les trois premiers packages font partie de **tidyverse**, une collection de packages utiles dans R, qui peuvent tous être installés à l'aide de `install.packages('tidyverse')`.
`dplyr` est utilisé pour le formattage et la transformation des données dans un dataframe. Le "d" dans "dplyr" signifie "dataframes" qui est la structure de données la plus utilisée pour stocker des jeux de données dans R.
## Voir les données
Commençons par charger le package afin que nous puissions obtenir les données dans des dataframes :
```{r, include=TRUE}
#loading the dplyr library
library(dplyr)
#loading data from MASS:biopsy
library(MASS)
class(biopsy)
```
```{r import_data}
#glimpse is a part of the dplyr package
glimpse(biopsy)
head(biopsy)
```
## Qu'est ce qu'une Tidy data?
**Qu'est-ce que cela signifie pour vos données d'être *tidy* ?**
**Tidy data** est un format normalisé et constitue une manière cohérente d'organiser vos données dans R.
Voici la définition d'une Tidy Data donnée par Hadley Wickham :
>Un ensemble de données est ordonné our desordonné selon la manière dont les lignes, les colonnes et les tableaux correspondent aux observations, aux variables et aux types. Une tidy data :
>
>* Chaque variable forme une colonne.
>
>* Chaque observation forme une ligne.
>
>* Chaque unité d'observation est une valeur dans la table.
>
*Voir [r4ds on tidy data](https://r4ds.had.co.nz/tidy-data.html){target="_blank"} pour plus d'info.*
**Quels sont les avantages des tidy data?**
* Uniformité : il est plus facile d'apprendre les outils pour travailler avec ces données car elles sont stockées de façon cohérentes.
* La plupart des fonctions de base en R utilisent des vecteurs de valeurs. Ainsi, avoir des variables en tant que colonnes/vecteurs permet à la nature vectorielle de R de briller.
**Pouvez-vous observer et dire pourquoi ces données sont en désordre ?**
* Les noms de colonnes tels que V1, V2 ne sont pas intuitifs dans leur contexte; c'est bon signe que la donnée est untidy.
* Ce ne sont pas des variables différentes, mais des valeurs d'une variable commune.
Nous allons maintenant voir comment transformer nos données en utilisant les fonctions de `dplyr` et ensuite voir comment comment rendre plus propre ces données.
## Tibbles
Un **tibble** est une structure moderne du dataframe.
Ceci est particulièrement utile pour les grands ensembles de données car *il n'imprime que les premières lignes*. Cela vous aide à faire face plus tôt aux problèmes, ce qui vous permet de nettoyer le code.
```{r, include=TRUE}
# Converting a df to a tibble
biopsy <- tbl_df(biopsy)
biopsy
```
## Test pour les valeurs manquantes
```{r, include=TRUE}
# Number of missing values in each column in the data frame
colSums(is.na(biopsy))
```
Le jeu de données contient des valeurs manquantes qui doivent être traitées.
## Remplacer les valeurs manquantes
Une façon de traiter les valeurs manquantes consiste à les recoder avec la moyenne de toutes les autres valeurs de cette colonne :
```{r, include=TRUE}
#change all the NAs to mean of the column
biopsy$V6[is.na(biopsy$V6)] <- mean(biopsy$V6, na.rm = TRUE)
colSums(is.na(biopsy))
```
Consultez notre chapitre sur [time series avec données manquantes](missingTS.html) pour plus d'informations sur la gestion des données manquantes.
## Vocabulaire de la manipulation de données
Voici le vocabulaire et les functions les plus couramment utilisés qui aident à manipuler les données et les résumer :
* Rename
* Select
* Mutate
* Filter
* Arrange
* Summarize
* Group_by
Les fonctions **Select** et **mutate** manipulent les *variables* (les colonnes du dataframe). **Filter** et **arrange** manipulent les *observations* (les lignes), enfin **summarize** manipule les *groupes* d'observations.
Toutes les fonctions de `dplyr` travaillent sur une copie des données et renvoient une copie modifiée. Ils ne changent **pas** le dataframe original. Si nous voulons accéder aux résultats par la suite, nous devons enregistrer la copie modifiée.
## Renommage
Les noms des colonnes dans nos données biopsy sont très vagues et ne nous donnent pas signification. Nous devons modifier les noms de la colonne afin qu'une personne extérieur puisse avoir une idée des valeurs auxquelles il fait référence.
```{r, include=TRUE}
rename(biopsy,
thickness = V1,cell_size = V2,
cell_shape = V3, marg_adhesion = V4,
epithelial_cell_size = V5, bare_nuclei = V6,
chromatin = V7, norm_nucleoli = V8, mitoses = V9)
```
Le tibble présenté ci-dessus n'est pas enregistré et ne peut plus être utilisé. Pour l'utiliser ensuite, nous l'enregistrons comme un nouveau tibble :
```{r, include=TRUE}
#saving the rename function output
biopsy_new<-rename(biopsy,
thickness = V1,cell_size = V2,
cell_shape = V3, marg_adhesion = V4,
epithelial_cell_size = V5, bare_nuclei = V6,
chromatin = V7, norm_nucleoli = V8, mitoses = V9)
head(biopsy_new,5)
```
Le dataframe `biopsy_new` peut maintenant être utilisé pour d'autres manipulations.
## Select
**Select** renvoie un sous-ensemble des données. Plus précisément, seules les colonnes spécifiées sont incluses.
Dans les données biopsy, nous n’avons pas besoin des variables "chromatin" et "mitoses". Alors, éliminons-les en utilisant un signe moins:
```{r, include=TRUE}
#selecting all except the columns chromatin and mitoses
biopsy_new<-select(biopsy_new,-chromatin,-mitoses)
head(biopsy_new,5)
```
## Mutate
La fonction **mutate** crée de nouvelles variables à partir des variables déjà existantes et les ajoute à l'ensemble de données. Il indique que les données déjà contenues mais n’ont jamais été affichées.
La variable "V6" contient les valeurs du bare nucleus de 1,00 à 10,00. Si nous voulons normaliser la variable, nous pouvons utiliser la fonction mutate :
```{r, include=TRUE}
#normalize the bare nuclei values
maximum_bare_nuclei<-max(biopsy_new$bare_nuclei,na.rm=TRUE)
biopsy_new<-mutate(biopsy_new,bare_nuclei=bare_nuclei/maximum_bare_nuclei)
head(biopsy_new,5)
```
## Filter
**Filter** est la fonction soeur de **select** pour les lignes; elle renvoie une copie modifiée qui ne contient que certaines lignes.
Cette fonction *filtre* les ligne en fonction du contenu et des conditions fournies en argument.
La fonction filter prend le dataframe comme premier argument. L'argument suivant contient une ou plusieures conditions logiques. Les lignes/observations qui vérifient ces conditions logiques sont retourné(e)s dans le résultat.
Dans notre example, on veut garder uniquement les données dont les cellules tuméreuses ont une certaine épaisseur. En pratique on garde celles dont l'épaisseur est supérieure à six, puisque la plupart des tumeurs malignes ont cette épaisseur dans le graphique d'épaisseur de cellule en fonction de la taille de cellule tuméreuse, groupé par classe :
```{r, include=TRUE}
library(ggplot2)
ggplot(biopsy_new)+
geom_point(aes(x=thickness,y=cell_size,color=class))+
ggtitle("Plot of Clump Thickness Vs Tumor Cell Size")
```
```{r, include=TRUE}
#normalize the bare nuclei values
biopsy_new<-filter(biopsy_new,thickness>5.5)
head(biopsy_new,5)
```
## Arrange
**Arrange** réordonne les lignes en fonction de leur contenu dans l'ordre croissant par défaut.
Les médecins voudraient voir les données dans l'ordre de la taille de la tumeur.
```{r, include=TRUE}
#arrange in the order of V2:cell size
arrange(biopsy_new,cell_size)
```
Cela montre les données en ordre croissant de la taille de la cellule.
Pour organiser les lignes dans l'ordre décroissant de V2, nous ajoutons la fonction `desc ()` à la variable avant de la passer dans arrange.
```{r, include=TRUE}
#arrange in the order of V2:cell size in decreasing order
arrange(biopsy_new,desc(cell_size))
```
Comme vous pouvez le constater, plusieurs lignes ont la même valeur de `V2:cell_size`. Pour palier ce problème, vous pouvez ajouter une autre variable à utiliser pour l'ordonnencement lorsque la première variable a la même valeur.
Ici nous utilisons V3 pour ordonner : par taille de cellule et pas ID :
```{r, include=TRUE}
#arrange in the order of V2:cell size
biopsy_new<-arrange(biopsy_new,desc(cell_size),desc(cell_shape),ID)
head(biopsy_new,5)
```
## Summarize & Group By
**Summarize** utilise les données pour créer un nouveau dataframe avec les statistiques récapitulatives telles que le minimum, le maximum, la moyenne, etc. Ces statistiques doivent être des fonctions agrégées qui prennent un vecteur de valeurs en entrée et une valeur unique en sortie.
La fonction **group_by** regroupe les données en fonction des valeurs des variables. Ceci, en plus de summarize, fait des observations des groupes de lignes de l’ensemble de données.
Les médecins voudraient connaître la taille maximale de la cellule et son épaisseur pour chacune des classes : bénigne et maligne. Cela peut être fait en regroupant les données par classe et en recherchant le maximum des variables cherchées :
```{r, include=TRUE}
biopsy_grouped <- group_by(biopsy_new,class)
summarize(biopsy_grouped, max(thickness), mean(cell_size), var(norm_nucleoli))
```
## Pipe Operator
Que faire si nous voulons utiliser les différentes fonctions **ensemble**?
Cela pourrait être fait en sauvegardant le résultat de chaque fonction dans une nouvelle variable et en l'utilisant pour la fonction suivante, comme nous l'avons fait ci-dessus. Cependant, ceci n'est pas recommandé :
1. Cela nécessite une saisie supplémentaire et un code plus long.
2. L'espace inutile est utilisé pour sauvegarder les différentes variables. Si les données sont volumineuses, cette méthode ralentit l’analyse.
L'opérateur **pipe** peut être utilisé à la place pour le même but. L'opérateur est placé entre l'objet et la fonction. Le pipe prend l'objet à sa gauche et le passe comme premier argument de la fonction à sa droite.
Le pipe fait partie du package `magrittr`. Cependant, ce package n'a pas besoin d'être chargé car `dplyr` nous simplifie la vie et l'importe pour nous :
```{r, include=TRUE}
biopsy_grouped <- biopsy_new %>%
group_by(class) %>%
summarize(max(thickness),mean(cell_size),var(norm_nucleoli))
head(biopsy_grouped)
```
## Nettoyer les données transformées
Regardez encore une fois les données désordonnées :
```{r, include=TRUE}
# Messy Data
head(biopsy_new,5)
```
La planification est nécessaire pour décider quelles colonnes nous devons garder inchangées, lesquelles modifier et quels noms doivent être donnés aux nouvelles colonnes. Les colonnes à conserver sont celles qui sont déjà tidy. Les colonnes à modifier sont celles qui ne sont pas de vraies variables mais en réalité des niveaux d'une autre variable.
Ainsi, les colonnes `ID` et la `class` sont déjà tidy. Celles-ci sont conservées telles quelles.
Les colonnes `V1:thickness`, `V2:cell_size`, `V3:cell_shape`, `V4:marg_adhesion`, `V5:epithelial_cell_size`, `V6:bare_nuclei`, et `V8:norm_nucleoli` ne sont pas de vraies variables mais des valeurs de la variable `Tumor_attributes`.
Nous pouvons résoudre ce problème avec `tidyr::gather()`, qui est utilisé pour convertir les données messy en tidy. La fonction `gather` prend le dataframe que nous voulons nettoyer entrée. Les deux paramètres suivants sont les noms des colonnes key et value columns du jeu de données tidy.
Dans notre exemple, key = 'Tumor_Atrributes' et value = 'Score'. Vous pouvez également préciser les colonnes que vous ne voulez pas ranger, à savoir ID et class:
```{r, include=TRUE}
#Tidy Data
library(tidyr)
tidy_df <- biopsy_new %>% gather(key = "Tumor_Attributes", value = "Score", -ID, -class)
tidy_df
```
## Liens utiles
- [r4ds on tidy data](https://r4ds.had.co.nz/tidy-data.html){target="_blank"}: C'est toujours mieux d'apprendre de la source, ainsi voici le livre écrit par Hadley Wickham.
- [DataCamp dplyr course](https://www.datacamp.com/courses/dplyr-data-manipulation-r-tutorial){target="_blank"}: Ce cours couvre les différentes fonctions de dplyr et comment manipuler les données.