Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
r_atelier3 [2017/09/07 13:42]
qcbs [Nuage de points]
r_atelier3 [2018/11/08 09:41] (current)
remimaglione [4. Ressources supplémentaires]
Line 6: Line 6:
  
 //Le contenu de cet atelier a été révisé par plusieurs membres du CSBQ. Si vous souhaitez y apporter des modifications,​ veuillez SVP contacter les coordonnateurs actuels de la série, listés sur la page d'​accueil//​ //Le contenu de cet atelier a été révisé par plusieurs membres du CSBQ. Si vous souhaitez y apporter des modifications,​ veuillez SVP contacter les coordonnateurs actuels de la série, listés sur la page d'​accueil//​
-====== Atelier 3: Introduction à ggplot2, tidyr & dplyr ======+====== Atelier 3: Introduction à ggplot2 ======
  
 Développé par : Xavier Giroux-Bougard,​ Maxwell Farrell, Amanda Winegardner,​ Étienne Low-Décarie,​ Monica Granados Développé par : Xavier Giroux-Bougard,​ Maxwell Farrell, Amanda Winegardner,​ Étienne Low-Décarie,​ Monica Granados
  
-**Résumé :** Pendant cet atelier, vous perfectionnerez vos compétences en visualisation et manipulation de jeux de données à l’aide de trois bibliothèques ​R : ggplot2, reshape et plyr. D’abord, vous explorerez la richesse de ggplot2 comme solution de rechange aux outils graphiques de base dans R, soit en explorant vos données visuellement et en produisant des figures dignes de publications scientifiques. Ensuite, nous présenterons tidyr et dplyr pour vous aider à transformer et à gérer le format de vos données ainsi que pour appliquer des fonctions simples ou complexes sur des sous-groupes de vos jeux de données. Cet atelier s’avérera utile non seulement pour les participants suivant notre série d’ateliers,​ mais également pour ceux et celles d’entre vous connaissant déjà le langage R et cherchant à maîtriser des outils plus avancés pour l'​analyse et la visualisation de vos données.+**Résumé :** Pendant cet atelier, vous perfectionnerez vos compétences en visualisation et manipulation de jeux de données à l’aide de la bibliothèques ggplot2. D’abord, vous explorerez la richesse de ggplot2 comme solution de rechange aux outils graphiques de base dans R, soit en explorant vos données visuellement et en produisant des figures dignes de publications scientifiques. Cet atelier s’avérera utile non seulement pour les participants suivant notre série d’ateliers,​ mais également pour ceux et celles d’entre vous connaissant déjà le langage R et cherchant à maîtriser des outils plus avancés pour l'​analyse et la visualisation de vos données.
  
-Lien vers la présentation Prezi associée : [[http://prezi.com/c8w7zdbfv0ap/|Prezi]]+**Lien vers la nouvelle ​[[https://qcbsrworkshops.github.io/Workshops/workshop03/​workshop03-fr/​workshop03-fr.html|présentation Rmarkdown]]** (en anglais seulement, la version française viendra sous peu!) 
  
-Téléchargez le script R pour cet atelier ​: {{:atelier3.r|Script}}+//S'il vous plaît essayez-la et dites aux coordonnateurs des ateliers R ce que vous en pensez!// 
 + 
 +Lien vers l'​ancienne [[http://​prezi.com/​c8w7zdbfv0ap/​|présentation Prezi]] 
 + 
 + 
 +Téléchargez le [[https://​raw.githubusercontent.com/​QCBSRworkshops/​Workshops/​dev/​workshop03/​workshop03-en/​script_workshop3.r|script R]] pour cet atelier.
 ===== 1. Tracer des graphiques avec R en utilisant la grammaire des graphiques (ggplot2) ===== ===== 1. Tracer des graphiques avec R en utilisant la grammaire des graphiques (ggplot2) =====
  
Line 69: Line 74:
 </​code>​ </​code>​
  
 +=== TEST ===
 {{ggplot2_1.png?​400 |}} {{ggplot2_1.png?​400 |}}
 +
  
 ==== Nuage de points (variables catégoriques) ==== ==== Nuage de points (variables catégoriques) ====
Line 248: Line 255:
 {{ggplot2_6.png?​400 |}} {{ggplot2_6.png?​400 |}}
  
-===== BONUS =====  
-Il est même possible d'​utiliser des émoticônes comme objets géométriques dans vos graphiques!!! Vous aurez tout simplement besoin du paquet ''​emojiGG''​ développé par David Lawrence Miller, disponibles depuis le répertoire GitHub: 
  
-<code rsplus | > 
-devtools::​install_github("​dill/​emoGG"​) 
-library(emoGG) 
-# vous devez faire une recherche 
-emoji_search("​bear"​) 
-830   bear 1f43b     ​animal 
-831   bear 1f43b     ​nature 
-832   bear 1f43b       wild 
- 
-ggplot(iris,​ aes(Sepal.Length,​ Sepal.Width,​ color = Species)) + 
-  geom_emoji(emoji="​1f337"​) 
-</​code>​ 
- 
-{{:​rplotbear.png?​400|}} 
- 
- 
----- 
 ===== ggplot2 - Défi #2 ===== ===== ggplot2 - Défi #2 =====
  
Line 500: Line 488:
  
 {{::​yeroon.png?​600|}} {{::​yeroon.png?​600|}}
- 
- 
  
 ---- ----
  
----- 
- 
-===== 2. Utiliser "​tidyr"​ pour réorganiser ses données ===== 
- 
-{{:​tidyrsticker.png?​200|}} 
-===== 2.1 Pourquoi réorganiser ses données ? ===== 
- 
-La réorganisation permet de modifier la structure des données tout en préservant l'​information contenue dans le jeu de données. Plusieurs fonctions dans R exigent ou fonctionnent mieux avec une structure de données qui n'est pas nécessairement propice à la lecture par l'oeil humain. 
- 
-En comparaison à l'​agrégation,​ où plusieurs cellules peuvent être regroupées pour créer un nouveau jeu de données (e.g. tableau des moyennes de plusieurs variables), la réorganisation maintient le même nombre de cellules. Le paquet ''​tidyr''​ permet de réorganiser nos jeu de données dans un format idéal pour nos tâches en aval, et ce à l'aide d'une syntaxe simple et logique. 
- 
-Commençons par installer et charger le paquet ''​tidyr''​ : 
-<code rsplus | > 
-if(!require(tidyr)){install.packages("​tidyr"​)} 
-library(tidyr) 
-</​code>​ 
- 
-==== Jeux de données "​airquality"​ ==== 
- 
-En plus du jeu de données ''​CO2'',​ nous allons utiliser le jeu de données ''​airquality''​ pour cette section de l'​atelier. 
- 
-Explorez la structure du jeu de données ''​airquality'':​ 
- 
-<code rsplus | > 
-?airquality 
-str(airquality) 
-head(airquality) 
-names(airquality) 
-</​code>​ 
- 
-Vous pouvez faire apparaître la liste des jeux de données disponibles dans R avec la commande suivante : ''​data()''​. 
- 
-===== 2.2 Données en format long vs large ===== 
- 
-Supposons que vous envoyez votre assistant de terrain pour faire la collecte de données des dimensions de plusieurs arbres sur un site de recherche, sois le diamètre à la hauteur de la poitrine (DHP) et la hauteur. Il ou elle vous revient avec le format "​dégât"​ (format large) suivant : 
- 
-<code rsplus | > 
-> degat <- data.frame(Species = c("​Chêne",​ "​Orme",​ "​Frêne"​),​ 
-                          DHP = c(12, 20, 13), 
-                         Haut = c(56, 85, 55)) 
-> degat 
-  Species DHP Haut 
-1   ​Chêne ​ 12   56 
-2    Orme  20   85 
-3   ​Frêne ​ 13   55 
-</​code>​ 
- 
-En contraste à l'​exemple ci-haut, un jeu de données en format “long” contient une colonne spécifiant les variables mesurées et une autre colonne contenant les mesures correspondantes (chaque colonne est une variable, et chaque rangée s'agit d'une observation unique). En ce sens, les jeux de données en "​long"​ sont plus "​propre"​ (//tidy// en anglais), parce qu'ils sont plus facilement interprétés par ''​R''​ pour nos visualisations et nos analyses. ​ 
- 
-Le format de vos données dépend de vos besoins d'​analyse et de visualisation,​ mais des fonctions et des paquets tels que ''​ggplot2''​ fonctionnent bien avec des données en format long. 
- 
-De plus, les données en format long peuvent être agrégées et réorganisées en format large plus facilement afin de produire des résumés ou de vérifier si un jeu de données est équilibré (i.e. avec le même nombre d'​observations par traitement). 
- 
-On utilise le paquet ''​tidyr''​ pour : 
- 
-  * 1. "​ramasser"​ les données (//gather data// en anglais; large --> long) 
-  * 2. "​éparpiller"​ les données (//spread data// en anglais; long --> large) 
- 
-Pour vous rappeler de ces deux termes, pensez au ménage chez soi: lorsqu'​on éparpille nos données (en format large) c'est le dégât, tandis que lorsqu'​on passe le balai, on ramasse les données pour les empiler de manières propres (en format long). 
-===== 2.3 Gather: Ramasser les données en format long ===== 
-<code rsplus | > 
-?gather 
-</​code>​ 
- 
-La plupart des paquets dans le "​Hadleyverse"​ requièrent un format "​long",​ c'​est-à-dire où chaque rangée est une observation unique, et chaque colonne est une variable. Utilisons la fonction ''​gather()''​ pour "​ramasser"​ nos données. ''​gather()''​ prend plusieurs colonnes et les empile dans deux colonnes: une colonne spécifiant la variable mesurée, et l'​autre spécifiant la mesure associée. Il faut inclure les arguments suivant dans la fonction : 
- 
-  * le jeu de données 
-  * le nom de la nouvelle colonne spécifiant la variable mesurée 
-  * le nom de la nouvelle colonne spécifiant la mesure associée 
-  * les colonnes qu'on veut empiler dans le jeu de données 
- 
-Voici une démonstration avec le jeu de données ''​degat''​ contenant les dimensions d'​arbres:​ 
- 
-<code rsplus | > 
-> degat.long <- gather(degat,​ dimension, cm, DHP, Haut) 
-> degat.long 
-  Species dimension cm 
-1   ​Chêne ​      DHP 12 
-2    Orme       DHP 20 
-3   ​Frêne ​      DHP 13 
-4   ​Chêne ​     Haut 56 
-5    Orme      Haut 85 
-6   ​Frêne ​     Haut 55 
-</​code>​ 
- 
-Essayons également avec le jeu de données ''​CO2'',​ soit en "​ramassant"​ les colonnes contant la concentration de CO2 (''​conc''​) et le CO2 absorbé (''​uptake''​) : 
- 
-<code rsplus | > 
-CO2.long <- gather(CO2, response, value, conc, uptake)  ​ 
-head(CO2) ​ 
-head(CO2.long) ​ 
-tail(CO2.long) 
-</​code>​ 
- 
- 
- 
- 
-===== 2.4 Spread: Éparpiller les données en format large ===== 
- 
-<code rsplus | > 
-?spread 
-</​code>​ 
- 
-La fonction ''​spread()''​ s'agit de l'​homologue inverse de ''​gather()'',​ donc elle nous permet de transformer nos données en format large. On utilise donc la même syntaxe: 
- 
-<code rsplus | > 
-> degat.large <- spread(degat.long,​ dimension, cm) 
-> degat.large 
-  Species DHP Haut 
-1   ​Chêne ​ 12   56 
-2   ​Frêne ​ 13   55 
-3    Orme  20   85 
-</​code>​ 
- 
----- 
-===== tidyr - Défi #4 ===== 
-//​Réorganisez le jeu de données ''​airquality''​ en format long (en ramassant toutes les colonnes sauf Month et Day). Ensuite, éparpillez-le en format large pour retrouver le format original de ''​airquality''://​ 
- 
-++++Solution| ​ 
-<code rsplus | > 
-air.long <- gather(airquality,​ variable, value, -Month, -Day) 
-# Notez que la syntaxe ici indique qu'on veut "​ramasser"​ toutes les colonnes sauf "​Month"​ et "​Day"​ 
-head(air.long) 
-air.wide <- spread(air.long , variable, value) 
-head(air.wide) 
-</​code>​ 
- 
-Le tableau ''​air.wide''​ a le même format que le jeu de données d'​origine ''​airquality''​ (bien que l'​ordre des colonnes ne soit pas le même). 
-++++ 
- 
----- 
- 
-===== 2.5 Separate : séparer une colonne en plusieurs colonnes ===== 
- 
-Il arrive parfois de travailler avec des jeux de données contenant une ou plusieurs variables dans la même colonne. Dans ces situations, la fonction ''​separate()''​ offre une solution facile pour séparer les variables pour que chacune d'​entre elle ait sa propre colonne. ​ 
- 
-À titre d'​exemple,​ créons un jeu de données fictif sur les poissons et le zooplancton : 
- 
-<code rsplus | > 
-set.seed(8) 
-gros.degat <- data.frame(id = 1:4, 
-                        trt = sample(rep(c('​controle',​ '​culture'​),​ each = 2)), 
-             ​zooplancton.T1 = runif(4), 
-                 ​poisson.T1 = runif(4), 
-             ​zooplancton.T2 = runif(4), 
-                 ​poisson.T2 = runif(4)) 
-  id      trt zooplancton.T1 poisson.T1 zooplancton.T2 ​ poisson.T2 
-1  1 controle ​     0.3215092 0.76914695 ​     0.4323914 0.001301721 
-2  2 controle ​     0.7189275 0.64449114 ​     0.5449621 0.264458864 
-3  3  culture ​     0.2908734 0.45704489 ​     0.1382243 0.276532247 
-4  4  culture ​     0.9322698 0.08930101 ​     0.9278123 0.521107042 
-</​code>​ 
- 
-Dans ce cas, notre première étape consisterait à "​ramasser"​ le jeu de données pour le transformer en format long. 
- 
-<code rsplus | > 
-> gros.degat.long <- gather(gros.degat,​ taxa, count, -id, -trt) 
-> head(gros.degat.long) 
-  id      trt           ​taxa ​    count 
-1  1 controle zooplancton.T1 0.3215092 
-2  2 controle zooplancton.T1 0.7189275 
-3  3  culture zooplancton.T1 0.2908734 
-4  4  culture zooplancton.T1 0.9322698 
-5  1 controle ​    ​poisson.T1 0.7691470 
-6  2 controle ​    ​poisson.T1 0.6444911 
-</​code>​ 
- 
-Petit rappel rapide, ici nous utilisons ''​-id''​ et ''​-trt'',​ ce qui est interprété par la fonction comme étant TOUTES les colonnes sauf ''​id''​ et ''​trt''​. Nous pourrions également énumeré chaque colonne comme ceci : ''​zooplancton.T1,​ poisson.T1, zooplancton.T2,​ poisson.T2''​. Quoique le résultat final est identique, l'​argument serait très long. 
- 
-Maintenant, supposons que nous voulons une colonne séparée contenant uniquement la variable du temps (T1 et T2) pour nos analyses. La fonction ''​separate()''​ nous permet de séparer le contenu d'une colonne en utilisant les arguments suivant: 
- 
-  * ''​data''​ : le jeu de données 
-  * ''​col''​ : le nom de la colonne que nous voulons séparer 
-  * ''​into''​ : les noms des 2 nouvelles colonnes 
-  * ''​by''​ : le critère expliquant où/comment séparer le contenu 
- 
-Dans notre exemple, nous voulons séparer le contenu de la colonne au point (''​.''​). Pour le dernier argument dans la fonction ''​separate()''​. Il faut donc utiliser un petit truc nous provenant des outils d'​expressions régulières pour travailler avec les chaînes de caractères (//​strings//​ en anglais) :  
- 
-<code rsplus | > 
-> gros.degat.long.sep <- separate(gros.degat.long,​ taxa, into = c("​especes",​ "​temps"​),​ sep = "​\\."​) 
-> head(gros.degat.long.sep) 
-  id      trt     ​especes temps     count 
-1  1 controle zooplancton ​   T1 0.3215092 
-2  2 controle zooplancton ​   T1 0.7189275 
-3  3  culture zooplancton ​   T1 0.2908734 
-4  4  culture zooplancton ​   T1 0.9322698 
-5  1 controle ​    ​poisson ​   T1 0.7691470 
-6  2 controle ​    ​poisson ​   T1 0.6444911 
-</​code>​ 
- 
-Ici, notons que la syntaxe ''​\\.''​ est requise parce qu'un point seul (''​.''​) est une carte frime (un joker) pour plusieurs fonctions dans le langage ''​R''​. Les ''​\\''​ servent donc à indiquer qu'on fait belle et bien référence au caractère ''​.''​. 
- 
- 
-===== 2.6 Combiner ggplot2 avec tidyr ===== 
- 
-==== Exemple montrant comment utiliser les formats long et large avec le jeu de données "​airquality"​ ==== 
- 
-<code rsplus | > 
-head(airquality) 
-  
- Ozone Solar.R Wind Temp Month Day 
-1    41     ​190 ​ 7.4   ​67 ​    ​5 ​  1 
-2    36     ​118 ​ 8.0   ​72 ​    ​5 ​  2 
-3    12     149 12.6   ​74 ​    ​5 ​  3 
-4    18     313 11.5   ​62 ​    ​5 ​  4 
-5    NA      NA 14.3   ​56 ​    ​5 ​  5 
-6    28      NA 14.9   ​66 ​    ​5 ​  6 
-</​code>​ 
-Le jeu de données est en format large où chaque variable mesurée (ozone, solar.r, wind and temp) ont leur propre colonne. 
- 
- 
-=== Diagrammes de diagnostic avec un format large et ggplot2 === 
- 
-**1:​** ​ Visualisez l'​étendue de chaque variable mesurée en fonction du mois. 
- 
-<code rsplus | > 
-fMonth <- factor(airquality$Month) # Convertit la variable "​Month"​ en facteur.  ​ 
-ozone.box <- ggplot(airquality,​ aes(x = fMonth, y = Ozone)) + geom_boxplot() 
-solar.box <- ggplot(airquality,​ aes(x = fMonth, y = Solar.R)) + geom_boxplot() 
-temp.box ​ <- ggplot(airquality,​ aes(x = fMonth, y = Temp)) + geom_boxplot() 
-wind.box ​ <- ggplot(airquality,​ aes(x = fMonth, y = Wind)) + geom_boxplot() 
-</​code>​ 
- 
-Vous pouvez utiliser la fonction ''​grid.arrange()''​ du paquet ''​gridExtra''​ pour regrouper tous ces diagrammes en une seule figure : 
-<code rsplus | > 
-combo.box <- grid.arrange(ozone.box,​ solar.box, temp.box, wind.box, nrow = 2)  
-# nrow = argument spécifiant le nombre de lignes sur lesquelles les diagrammes seront affichés. 
-</​code>​ 
- 
-On obtient quatre diagrammes distincts sur un seul panneau. ​ 
-Prenez note que l'axe des y est différent pour chaque variable :  
- 
-{{::​airquality_grid.png?​nolink|600}} 
- 
- 
-**2.** On peut faire la même chose, mais en représentant les variables en fonction du jour pour chaque mois séparément : 
- 
-<code rsplus | > 
-ozone.graph <- ggplot(airquality,​ aes(x = Day, y = Ozone)) + 
-    geom_point() + 
-    geom_smooth() + 
-    facet_wrap(~ Month, nrow = 2) 
- 
-solar.graph <- ggplot(airquality,​ aes(x = Day, y = Solar.R)) + 
-    geom_point() + 
-    geom_smooth() +  
-    facet_wrap(~ Month, nrow = 2) 
- 
-wind.graph <- ggplot(airquality,​ aes(x = Day, y = Wind)) + 
-    geom_point() + 
-    geom_smooth() +  
-    facet_wrap(~ Month, nrow = 2) 
- 
-temp.graph <- ggplot(airquality,​ aes(x = Day, y = Temp)) + 
-    geom_point() +  
-    geom_smooth() +  
-    facet_wrap(~ Month, nrow = 2) 
-</​code>​ 
- 
-On peut également regrouper tous ces diagrammes (même si ce n'est pas très joli pour le moment !) : 
-<code rsplus | > 
-combo.facets <- grid.arrange(ozone.graph,​ solar.graph,​ wind.graph, temp.graph, nrow = 4) 
-</​code>​ 
- 
-{{::​airquality_faceted.png?​nolink|}} 
- 
-//MAIS//, comment faire pour utiliser la fonction ''​facet_wrap()''​ avec des variables mesurées au lieu des variables "​Month"​ et "​Day"​ ?  
- 
-**Il faut réorganiser les données en format long !** 
-//(Voir la section 2.3)// ​ 
- 
-<code rsplus | > 
-air.long <- gather(airquality,​ variable, value, -Month, -Day) 
-air.large <- spread(air.long , variable, value) 
-</​code>​ 
- 
-Utilisez air.long: 
-<code rsplus | > 
-fMonth.long <- factor(air.long$Month) 
-meteo <- ggplot(air.long,​ aes(x = fMonth.long,​ y = value)) + 
-    geom_boxplot() +  
-    facet_wrap(~ variable, nrow = 2) 
-meteo 
-</​code>​ 
- 
-Comparez les diagrammes ''​meteo''​ avec ceux de ''​combo.box''​ : 
- 
-{{::​weather_plot.png?​nolink|600}} 
- 
-Dans chacun des cas, on a utilisé les mêmes données, mais les graphiques sont légèrement différents. 
- 
-Les variables de l'​objet ''​meteo''​ sont sur la même échelle en utilisant la fonction ''​facet_wrap()''​. 
-Ça peut être utile dans plusieurs circonstances,​ mais ça ne permet pas de voir toute la variation de la variable "​Wind"​. 
-  
-Dans ce cas, on peut modifier le script pour permettre à R de déterminer l'​échelle pour chaque variable avec l'​argument ''​scales''​ : 
-<code rsplus | > 
-meteo <- meteo + facet_wrap(~ variable, nrow = 2, scales = "​free"​) 
-meteo 
-</​code>​ 
- 
-{{::​weather_scaled_free.png?​nolink|600}} 
- 
-On peut aussi utiliser le format long pour créer un graphique qui inclut **toutes les variables sur un seul graphique** : 
-<code rsplus | > 
-meteo2 <- ggplot(air.long,​ aes(x = Day, y = value, colour = variable)) + 
-    geom_point() +  
-    facet_wrap(~ Month, nrow = 1) 
-meteo2 
-</​code>​ 
- 
-{{::​weather2.png?​nolink|}} 
- 
- 
-===== 3. Manipulation de données avec dplyr ===== 
- 
-{{:​dplyrsticker.png?​200|}} 
- 
-**MANIPULATION EXTRÊME DE JEUX DE DONNÉES** 
- 
-===== 3.1 Intro - la mission de dplyr ===== 
- 
-Souvent, on doit faire appel à une gamme d'​outils complexes pour manipuler nos jeux de données. La mission de ''​dplyr''​ est de simplifier nos tâches de manipulation en distillant toutes les opérations communes sous un même toit. Le résultat est une collection de fonctions ayant une syntaxe simple qu'on peut exécuter à l'aide de verbes intuitifs. Le pont entre nos pensées/​intentions et le langage ''​R''​ est donc franchit avec plus de fluidité. En plus d'​être facile à utiliser, le paquet ''​dplyr''​ est exceptionnel pour les raisons suivantes : 
- 
-  * il peut traiter des gros jeux de données très rapidement (écrit en langage ''​Cpp''​) 
-  * sa fonctionnalité est bien intégrée dans RStudio et autres paquets du Hadleyverse 
-  * il peut établir des connections à des bases de données SQL, et traduire votre code en requête SQL 
-  * c'est le Batman des paquets ''​R''​ (maîtrise la peur des données et adopte des technologies avancées) 
- 
-===== 3.2 Fonctions dplyr de base ===== 
- 
-Au coeur du paquet ''​dplyr'',​ on retrouve des "​verbes"​ essentiels qui nous permettent d'​accomplir la majeure partie de nos opérations de manipulation de données. Voici 4 verbes qui exécutent les opérations les plus commune : 
- 
-  * ''​select()''​ : sélectionne des colonnes dans un jeu de données 
-  * ''​filter()''​ : filtre des rangées suivant les critères spécifiés 
-  * ''​arrange()''​ : trie les données d'une colonne en ordre croissant ou décroissant 
-  * ''​mutate()''​ : crée des données dans une nouvelle colonne (ou transforme une colonne existante) 
- 
-Commençons par installer et charger le paquet ''​dplyr''​ afin d'​explorer ces fonctions : 
- 
-<code rsplus | > 
-if(!require(dplyr)){install.packages("​dplyr"​)} 
-library(dplyr) 
-</​code>​ 
- 
-Dans les exemples et les défis qui suivent, nous utiliserons les jeux de données ''​airquality''​ et ''​ChickWeight''​ : 
- 
-<code rsplus | > 
-?airquality 
-data(airquality) 
-?​ChickWeight 
-data(ChickWeight) 
-</​code>​ 
- 
-==== Sélection de colonnes avec ''​select()''​ ====  
- 
-Le jeu de données ''​airquality''​ contient plusieurs colonnes : 
- 
-<code rsplus | > 
-> head(airquality) 
-  Ozone Solar.R Wind Temp Month Day 
-1    41     ​190 ​ 7.4   ​67 ​    ​5 ​  1 
-2    36     ​118 ​ 8.0   ​72 ​    ​5 ​  2 
-3    12     149 12.6   ​74 ​    ​5 ​  3 
-4    18     313 11.5   ​62 ​    ​5 ​  4 
-5    NA      NA 14.3   ​56 ​    ​5 ​  5 
-6    28      NA 14.9   ​66 ​    ​5 ​  6 
-</​code>​ 
- 
-À titre d'​exemple,​ supposons qu'on s'​intéresse à la variation de la variable ''​Ozone''​ avec le temps. À l'aide de la fonction ''​select()'',​ on peut retenir uniquement les colonnes requises pour nos analyses : 
- 
-<code rsplus | > 
-> ozone <- select(airquality,​ Ozone, Month, Day) 
-> head(ozone) 
-  Ozone Month Day 
-1    41     ​5 ​  1 
-2    36     ​5 ​  2 
-3    12     ​5 ​  3 
-4    18     ​5 ​  4 
-5    NA     ​5 ​  5 
-6    28     ​5 ​  6 
-</​code>​ 
- 
-Comme vous pouvez voir, la syntaxe générale de la fonction est comme suit : ''​select(donnés,​ colonne1, colonne2, ...)''​. La plupart des fonctions ''​dplyr''​ sont exécutées avec une syntaxe simple similaire. ​ 
- 
-==== Sélection d'un sous-ensemble de rangées avec ''​filter()''​ ====  
- 
-Souvent on s'​intéresse à un sous-ensemble spécifique de notre jeu de données. Par exemple, supposons qu'on s'​intéresse aux périodes de canicules du mois d'​août dans le jeu de données ''​airquality''​ : 
- 
-<code rsplus | > 
-> aout <- filter(airquality,​ Month == 8, Temp >= 90) 
-> head(aout) 
-  Ozone Solar.R Wind Temp Month Day 
-1    89     229 10.3   ​90 ​    ​8 ​  8 
-2   ​110 ​    ​207 ​ 8.0   ​90 ​    ​8 ​  9 
-3    NA     ​222 ​ 8.6   ​92 ​    ​8 ​ 10 
-4    76     ​203 ​ 9.7   ​97 ​    ​8 ​ 28 
-5   ​118 ​    ​225 ​ 2.3   ​94 ​    ​8 ​ 29 
-6    84     ​237 ​ 6.3   ​96 ​    ​8 ​ 30 
-</​code>​ 
- 
-Ici, le format général de la syntaxe utilisé est comme suit : ''​filter(dataframe,​ proposition logique 1, proposition logique 2, ...)''​. On se rappelle que la réponse à une proposition logique est VRAI ou FAUX (TRUE or FALSE). La fonction ''​filter()''​ retient uniquement les rangées pour lesquelles la réponse à la proposition logique est VRAI. On peut aussi utiliser cette fonction sur des chaînes de caractères (//​strings//​) et des facteurs (//​factors//​).  ​ 
- 
-==== Triage avec ''​arrange()''​ ====  
- 
-Parfois on travaille avec des jeux de données qui doivent être analysé et/ou visualisé dans un ordre spécifique (//e.g.// série temporelle). Avec la fonction ''​arrange()'',​ on peut trier le contenu d'une colonne en ordre croissant ou décroissant (alphabétiquement ou numériquement). Commençons par créer une version de ''​airquality''​ dans un ordre aléatoire : 
- 
-<code rsplus | > 
-> air_degat <- sample_frac(airquality,​ 1) 
-> head(air_degat) 
-    Ozone Solar.R Wind Temp Month Day 
-21      1       ​8 ​ 9.7   ​59 ​    ​5 ​ 21 
-42     ​NA ​    259 10.9   ​93 ​    ​6 ​ 11 
-151    14     191 14.3   ​75 ​    ​9 ​ 28 
-108    22      71 10.3   ​77 ​    ​8 ​ 16 
-8      19      99 13.8   ​59 ​    ​5 ​  8 
-104    44     192 11.5   ​86 ​    ​8 ​ 12 
-</​code>​ 
- 
-Maintenant, voici comment réarranger le jeu de données en ordre chronologique,​ soit en ordre croissant de ''​Month''​ et ensuite en ordre croissant de ''​Day''​ : 
- 
-<code rsplus | > 
-> air_chron <- arrange(air_degat,​ Month, Day) 
-> head(air_chron) 
-  Ozone Solar.R Wind Temp Month Day 
-1    41     ​190 ​ 7.4   ​67 ​    ​5 ​  1 
-2    36     ​118 ​ 8.0   ​72 ​    ​5 ​  2 
-3    12     149 12.6   ​74 ​    ​5 ​  3 
-4    18     313 11.5   ​62 ​    ​5 ​  4 
-5    NA      NA 14.3   ​56 ​    ​5 ​  5 
-6    28      NA 14.9   ​66 ​    ​5 ​  6 
-</​code>​ 
- 
-Notez qu'on peut également réarranger en ordre décroissant en enveloppant la variable d'​intérêt avec la fonction ''​desc()''​ au sein de la fonction ''​arrange()''​. ​ 
- 
-==== Créer des nouvelles variables avec ''​mutate()''​ ====  
- 
-Au delà de l'​extraction de sous-ensemble ou du triage, une des opérations les plus communes et les plus utiles s'agit de transformer nos variables existantes afin de générer des nouvelles variables. Par exemple, dans le jeu de données ''​airquality''​ la température est en degré Fahrenheit. Transformons la variable ''​Temp''​ en degré Celsius : 
- 
-<code rsplus | > 
-> airquality_C <- mutate(airquality,​ Temp_C = (Temp-32)*(5/​9)) 
-> head(airquality_C) 
-  Ozone Solar.R Wind Temp Month Day   ​Temp_C 
-1    41     ​190 ​ 7.4   ​67 ​    ​5 ​  1 19.44444 
-2    36     ​118 ​ 8.0   ​72 ​    ​5 ​  2 22.22222 
-3    12     149 12.6   ​74 ​    ​5 ​  3 23.33333 
-4    18     313 11.5   ​62 ​    ​5 ​  4 16.66667 
-5    NA      NA 14.3   ​56 ​    ​5 ​  5 13.33333 
-6    28      NA 14.9   ​66 ​    ​5 ​  6 18.88889 
-</​code>​ 
- 
-Notez que dans notre exemple, la syntaxe est très simple. Cependant, à l'​intérieur d'un seul appel de la fonction ''​mutate()''​ on peut: 
- 
-  * remplacer le contenu de colonnes existantes (en conservant le même nom) 
-  * créer plusieurs nouvelles colonnes ​ 
-  * créer des nouvelles colonnes calculées depuis des nouvelles variables créés en amont 
-  
-===== 3.3 dplyr et magrittr, don du ciel ===== 
- 
-{{:​magrittrsticker.png?​200|}} 
- 
-Le paquet ''​magrittr''​ introduit un nouvel outil commun dans plusieurs langages informatiques : le **pipe**. Le "​pipe"​ (un tuyau en français) permet de relier nos fonctions en redirigeant la sortie (//​output//​) d'une fonction en amont vers l'​entrée (//input//) d'une fonction en aval. Le "​pipe"​ fournit par le paquet ''​magrittr''​ s'​écrit come ceci : ''​%>​%''​. Lorsqu'​on l'​utilise en combo avec ''​dplyr'',​ le "​pipe"​ de ''​magrittr''​ nous permet d'​accéder à la flexibilité et l'​omnipotence du paquet. Pour vous familiariser avec ce type de flux de travail, nous utiliserons ''​dplyr''​ avec ''​magrittr''​ pour le reste de l'​atelier. Installons et chargeons le paquet : 
- 
-<code rsplus | > 
-if(!require(magrittr)){install.packages("​magrittr"​)} 
-library(magrittr) 
-</​code>​ 
- 
-L'​utilisation de ''​magrittr''​ est très intuitif. Nous allons démontrer son fonctionnement en combinant les exemples ci-haut. Supposons qu'on veut créer un sous-ensemble de ''​airquality''​ pour le mois de juin, et ensuite convertir la variable de la température en degré Celsius. Si on procède comme auparavant, soit une étape à la fois, notre code lirait comme suit : 
- 
-<code rsplus | > 
-juin_C <- mutate(filter(airquality,​ Month == 6), Temp_C = (Temp-32)*(5/​9)) 
-</​code>  ​ 
- 
-Ce code peut être difficile à lire parce que l'​ordre des opérations exécutées commence au centre et se lit vers l'​extérieur jusqu'​à la fonction enveloppant le tout. Plus on ajoute des opérations,​ plus le code devient illisible. Au lieu d'​envelopper tous les fonctions, on peut écrire les opérations en ordre d'​exécutions et les relier à l'aide du "​pipe"​ ''​%>​%''​ : 
- 
-<code rsplus | > 
-juin_C <- airquality %>​% ​ 
-    filter(Month == 6) %>% 
-    mutate(Temp_C = (Temp-32)*(5/​9)) 
-</​code> ​ 
- 
-Notez qu'au sein de chaque fonction, nous avons omis le premier argument spécifiant le jeu de données. Au lieu, nous inscrivons le jeu de données avant les opérations et on le "​pipe"​ jusqu'​à la prochaine fonction à l'aide de ''​%>​%''​. Rappelez-vous que cette approche est semblable à ''​ggplot2'',​ puisque nous spécifions le jeu de données à tracer une seule fois, et chaque "​couche"​ supplémentaire est ajouté avec un ''​+''​ pour relier l'​information. En utilisant le "​pipe",​ le code est moins redondant. De plus, il se lit et s'​écrit dans le même ordre que l'​exécution des opérations,​ ce qui facilite/​accélère la traduction de nos pensées en code ainsi que la lecture et la compréhension du code écrit par nos collègues. Lorsque nos opérations de manipulation de données deviennent plus complexes et requièrent plusieurs étapes, on s'​aperçoit rapidement que ''​magrittr''​ offre une approche puissante et élégante pour la rédaction de notre code ''​dplyr''​. ​ 
- 
-**BONUS :** Dans RStudio, on peut insérer le "​pipe"​ rapidement avec la combinaison des touches suivantes sur vos claviers : ''​Ctrl''​ (or ''​Cmd''​ sur Mac) +''​Shift''​+''​M''​. 
- 
-===== 3.4 dplyr - Opérations de regroupement et d'​aggrégation ===== 
- 
-Les verbes ''​dplyr''​ couvert jusqu'​à prsent sont certes utiles individuellement,​ mais ils deviennent particulièrement puissant lorsqu'​on les relie ensemble avec le "​pipe"​ (''​%>​%''​) et lorsqu'​on les applique sur des sous-groupes d'​observations. Les fonctions ''​dplyr''​ suivantes nous permettent donc de séparer nos jeu de données en groupes distincts sur lesquels on peut exécuter des opérations individuelles,​ comme des fonctions d'​aggrégation : 
- 
-  * ''​group_by()'':​ regrouper le jeu de donner par un facteur pour les opérations en aval (comme ''​summarise''​) 
-  * ''​summarise()'':​ créer un sommaire de variables au sein de groupes distincts dans un jeu de données en utilisant des fonctions d'​aggrégation (//e.g.// ''​min()'',​ ''​max()'',​ ''​mean()'',​ etc...) 
- 
-Ces deux verbes fournissent la structure requise pour la stratégie Split-Apply-Combine (Séparer-Appliquer-Combiner) originalement introduite dans le paquet ''​plyr'',​ l'​ancêtre de ''​dplyr''​. Voici un exemple de l'​usage de ces deux fonctions à l'aide du jeu de données ''​airquality''​. Supposons qu'on s'​intéresse à la température moyenne et l'​écart type pour chaque mois: 
- 
-<code rsplus | > 
-> mois_moy <- airquality %>​% ​ 
-      group_by(Month) %>​% ​ 
-      summarise(mean_temp = mean(Temp), 
-                sd_temp = sd(Temp)) ​ 
-mois_moy 
-Source: local data frame [5 x 3] 
- 
-  Month mean_temp ​ sd_temp 
-  (int)     ​(dbl) ​   (dbl) 
-1     ​5 ​ 65.54839 6.854870 
-2     ​6 ​ 79.10000 6.598589 
-3     ​7 ​ 83.90323 4.315513 
-4     ​8 ​ 83.96774 6.585256 
-5     ​9 ​ 76.90000 8.355671 
-</​code>​ 
- 
----- 
- 
-===== dplyr Défi #5 ===== 
-//En utilisant le jeu de données ''​ChickWeight'',​ créez un tableau sommaire dans lequel on retrouve la différence de masse entre le maximum et le minimum de la masse enregistré pour chaque poussin dans l'​étude. Utilisez les verbes ''​dplyr''​ et le "​pipe"​ ''​%>​%''​.//​ 
- 
-++++Solution| ​ 
-<code rsplus | > 
-> mass_diff <- ChickWeight %>​% ​ 
-     ​group_by(Chick) %>​% ​ 
-     ​summarise(mass_diff = max(weight) - min(weight)) 
-> mass_diff 
-Source: local data frame [50 x 2] 
- 
-    Chick weight_diff 
-   ​(fctr) ​      (dbl) 
-1      18           4 
-2      16          16 
-3      15          27 
-4      13          55 
-5       ​9 ​         58 
-6      20          76 
-7      10          83 
-8       ​8 ​         92 
-9      17         100 
-10     ​19 ​        114 
-..    ...         ... 
-</​code>​ 
- 
-Notez qu'ici on mesure simplement la différence de masse entre le maximum et le minimum. Il ne s'agit donc pas de la différence de masse entre le début et la fin de l'​étude (différence en ordre chronologique de la masse). Inspectez de plus près les observations liées au poussin # 18 : 
-<code rsplus | > 
-> poussin_18 <- ChickWeight %>% filter(Chick == 18) 
-> poussin_18 
-  weight Time Chick Diet 
-1     ​39 ​   0    18    1 
-2     ​35 ​   2    18    1 
-</​code>​ 
- 
-On s'​aperçoit ici que le poussin a en fait perdu de la masse (il est probablement décédé, puisqu'​il a seulement 2 observations). D'un point de vue scientifique,​ on pourrait s'​intéresser davantage à la question : quelle ''​Diet''​ engendre un gain de masse plus important chez les poussins individuels. On pourrait donc calculer la différence de masse entre le début et la fin avec deux autres fonctions utiles dans ''​dplyr''​ : ''​first()''​ et ''​last()''​ nous permettent d'​accéder à la première et la deuxième observation d'un sous-groupe,​ respectivement. 
-++++ 
----- 
- 
-==== Indice pour les ninjas ==== 
- 
-Notez qu'on peut regrouper un jeu de données par plus d'un facteur, en suivant la syntaxe générale suivante : 
- 
-''​group_by(groupe1,​ groupe2, ...)''​ 
- 
-Au sein de "​group_by()",​ on peut regrouper par plusieurs variables pour créer un "​oignon"​ de sous-ensembles,​ et chaque utilisation distinct de la fonction ''​summarise()''​ élimine une couche de l'​oignon en commençant par la couche extérieur, donc la dernière variable dans ''​group_by()''​ qui s'agit de ''​groupe2''​ dans cet exemple. Ainsi, dans l'​exemple ci-haut, si on utilise la fonction ''​summarise()''​ une seule fois en aval: 
- 
-''​group_by(groupe1,​ groupe2) %>% summarise(x = mean(y))''​ 
- 
-le ''​groupe2''​ est éliminé, et le jeu de données devient ensuite groupé par ''​groupe1''​. Si on utilise summarise deux fois: 
- 
-''​group_by(groupe1,​ groupe2) %>% summarise(x = mean(y)) %>% summarise(z = mean(a+b))''​ 
- 
-le jeu de données produit n'est plus groupé en sous-ensemble pour les opérations en aval. 
- 
----- 
- 
-===== dplyr NINJA Défi #6 ===== 
-// En utilisant le jeu de données ''​ChickWeight'',​ créez un tableau sommaire nous indiquant, pour chaque ''​Diet'',​ la moyenne de la différence de masse entre la fin et le début de l'​étude pour chaque poussin. Utilisez les verbes ''​dplyr''​ et le pipe ''​%>​%''​. (Indice : les fonctions ''​first()''​ et ''​last()''​ pourrait s'​avérer utile)// ​ 
- 
-++++Solution| ​ 
-<code rsplus | > 
-> diet_mass <- ChickWeight %>​% ​ 
-      group_by(Diet,​ Chick) %>​% ​ 
-      summarise(gain_masse = last(weight) - first(weight)) %>​% ​ 
-      summarise(gain_moyen = mean(gain_masse)) 
-> diet_mass 
-Source: local data frame [4 x 2] 
- 
-    Diet gain_moyen 
-  (fctr) ​     (dbl) 
-1      1      114.9 
-2      2      174.0 
-3      3      229.5 
-4      4      188.3 
-</​code>​ 
-Cette solution démontre bien la simplicité et l'​élégance de la syntaxe de ''​dplyr''​ et ''​magrittr''​ en situation où nous devons manipuler nos données en plusieurs étapes consécutives. Un défi encore plus difficile, même pour les experts en fonctions dans ''​R''​ de base, serait de reproduire les mêmes opérations avec moins de touches de votre clavier. Nous avons essayé et nous avons échoué... Peut-être sommes-nous trop habitués à ''​dplyr''​ maintenant? 
- 
-++++ 
- 
----- 
- 
-===== 3.5 dplyr - fusion de tableaux de données ===== 
- 
-En plus de tous les fonctions que nous avons exploré aujourd'​hui,​ ''​dplyr''​ offre également quelques fonctions fort utile nous permettant de réunir 2 tableau de données. La syntaxe de ces fonctions est relativement simple comparé aux autres paquets dans l'​arsenal de ''​R''​ : 
- 
-  * ''​left_join()''​ 
-  * ''​right_join()''​ 
-  * ''​inner_join()''​ 
-  * ''​anti_join()''​ 
- 
-Ces fonctions vont au-delà du matériel d'​introduction dans cet atelier, mais on vous invite à les explorer et les considérer pour vos propres besoins de manipulation de données. ​ 
  
 ===== 4. Ressources supplémentaires ===== ===== 4. Ressources supplémentaires =====
  
-Voici quelques ressources intéressantes pour continuer votre apprentissage ​des paquets ​''​ggplot2'',​ ''​tidyr''​ et ''​dplyr''​. On s'en est d'​ailleurs servi comme inspiration pour la matériel couvert aujourd'​hui :+Voici quelques ressources intéressantes pour continuer votre apprentissage ​du paquet ​''​ggplot2''​. On s'en est d'​ailleurs servi comme inspiration pour la matériel couvert aujourd'​hui :
  
 //ggplot2// //ggplot2//
 +  * [[https://​www.r-graph-gallery.com|Gallerie de graphique possible dans R]]
 +  * [[http://​sape.inf.usi.ch/​quick-reference/​ggplot2|Guide de référence de ggplot2 par le SAPE]]
   * [[http://​shinyapps.stat.ubc.ca/​r-graph-catalog/​|Le Catalog de Diagramme R]]   * [[http://​shinyapps.stat.ubc.ca/​r-graph-catalog/​|Le Catalog de Diagramme R]]
   * [[https://​www.rstudio.com/​wp-content/​uploads/​2015/​03/​ggplot2-cheatsheet.pdf|L'​aide-mémoire ggplot2 de RStudio]]   * [[https://​www.rstudio.com/​wp-content/​uploads/​2015/​03/​ggplot2-cheatsheet.pdf|L'​aide-mémoire ggplot2 de RStudio]]
Line 1122: Line 505:
   * [[http://​stat405.had.co.nz/​lectures/​11-adv-data-manip.pdf]]   * [[http://​stat405.had.co.nz/​lectures/​11-adv-data-manip.pdf]]
   * [[http://​stat405.had.co.nz/​lectures/​19-tables.pdf]]   * [[http://​stat405.had.co.nz/​lectures/​19-tables.pdf]]
- 
-//dplyr and tidyr// 
-  * [[https://​www.rstudio.com/​wp-content/​uploads/​2015/​02/​data-wrangling-cheatsheet.pdf|L'​aide-mémoire de manipulation de données de RStudio]] 
-  * [[https://​cran.rstudio.com/​web/​packages/​dplyr/​vignettes/​introduction.html|CRAN Intro to dplyr]] 
-  * [[http://​seananderson.ca/​2014/​09/​13/​dplyr-intro.html|Sean Anderson'​s Intro to dplyr and pipes]] 
-  * [[https://​rpubs.com/​bradleyboehmke/​data_wrangling|Bradley Boehmke'​s Intro to data wrangling]] 
- 
  
 **BONUS !** Allez jeter un coup d'oeil sur le format des scripts recommandé par Hadley afin de faciliter la compréhension et le partage de ceux-ci : **BONUS !** Allez jeter un coup d'oeil sur le format des scripts recommandé par Hadley afin de faciliter la compréhension et le partage de ceux-ci :
   * [[http://​adv-r.had.co.nz/​Style.html]]   * [[http://​adv-r.had.co.nz/​Style.html]]