class: center, middle, inverse, title-slide .title[ # Atelier 2: Charger et manipuler des données ] .subtitle[ ## Série d’ateliers R du CSBQ ] .author[ ### Centre de la science de la biodiversité du Québec ] --- class: inverse, center, middle # À propos de cet atelier [![badge](https://img.shields.io/static/v1?style=flat-square&label=Diapos&message=02&color=red&logo=html5)](https://r.qcbs.ca/workshop02/pres-fr/workshop02-pres-fr.html) [![badge](https://img.shields.io/static/v1?style=flat-square&label=livre&message=02&logo=github)](https://r.qcbs.cao/workshop02/book-fr/index.html) [![badge](https://img.shields.io/static/v1?style=flat-square&label=script&message=02&color=2a50b8&logo=r)](https://r.qcbs.ca/workshop02/book-fr/workshop02-script-fr.R) [![badge](https://img.shields.io/static/v1?style=flat-square&label=repo&message=dev&color=6f42c1&logo=github)](https://github.com/QCBSRworkshops/workshop02) --- # Packages requis * [dplyr](https://cran.r-project.org/package=dplyr) * [tidyr](https://cran.r-project.org/package=tidyr) * [magrittr](https://cran.r-project.org/package=magrittr) <br> ```R install.packages(c('dplyr', 'tidyr', 'magrittr')) ``` --- # Objectifs d'apprentissage <br> ##### 1. Créer un projet RStudio ##### 2. Écrire un script dans R ##### 3. Charger, explorer et enregistrer des données ##### 4. Manipuler des jeux de données avec `tidyr`, `dplyr`, `maggritr` --- class: inverse, center, middle # Créer un projet RStudio <hr> --- # Les projets RStudio * Qu'est-ce qu'un projet RStudio ? - Les projets RStudio permettent l'organisation de son travail et l'accès facile à tous les fichiers requis pour une analyse. - Tous les fichiers, scripts, et documentation utilisés pour une analyse sont reliés ensemble dans un même projet par un fichier *.Rproj*. * L'utilisation de projets RStudio facilite la **reproducibilité** et le partage de données, de scripts, et de leur documentation. --- # Créer un projet dans RStudio Pour créer un projet dans RStudio, allez dans le menu Fichier puis sélectionnez **Nouveau projet** (*File* -> *New Project*). .center[ ![:scale 60%](images/0_Create_a_new_project.png)] --- # Un projet = un dossier Organisez vos fichiers ! .center[ ![:scale 60%](images/0_folderData1.png)] --- # Préparer des données pour l'importation dans R * Vous devriez enregistrer les fichiers à importer dans R en tant que fichiers "*comma separated values*" (**.csv**) * Les fichiers .csv peuvent être créés par presque toutes les applications (Excel, GoogleDocs, LibreOffice, etc.) * Fichier -> Enregistrer sous **.csv**… .center[ ![:scale 45%](images/Excel_csv_good_bad/excel_vs_csv.png) ] --- # Bien nommer les fichiers Évitez d’utiliser des espaces, des accents ou des caractères spéciaux pour vos noms .pull-left[ **Non:** - final.csv (*pas-informatif !*) - safnnejs.csv (*C'est n'importe quoi!*) - 1-4.csv (*Eviter d'utiliser des chiffres!*) - Ne.pas.separer.par.des.points.csv (*Peut causer des erreurs de lecture de fichier !*) ] .pull-right[ **Oui:** - rawDatasetAgo2017.csv - co2_concentrations_QB.csv - 01_figIntro.R ] --- # Bien nommer les variables * Utilisez des noms de variables courts et informatifs (i.e. "Temps_1" au lieu de "Temps de la première mesure") * Les valeurs des colonnes doivent correspondre à l'usage prévu .pull-left[ **Bien !** - Measurements - SpeciesNames - Site ] .pull-right[ **Pas bien !** - a - 3 - supernomunpeutroplong] <br> <br> Regardez le guide [tidyverse](https://style.tidyverse.org/) pour plus de conseils. --- # Conseils pour préparer les données .pull-left[ * Pas de texte dans les colonnes de mode numérique * Pas d'espace * Identifiez les valeurs manquantes par NA ("not available") * Faites attention aux erreurs typographiques! ] .pull-right[ * Évitez les valeurs numériques pour les variables n'ayant pas un sens numérique (i.e. individu, réplicat, traitement) * Utilisez un format uniforme pour les dates, les chiffres, etc. * N'ajoutez pas de notes, d'entêtes supplémentaires, ou de cellules fusionnées! * Une variable par colonne! ] <br> <br> Lire le paper de [Broman & Woo (2017)](https://doi.org/10.1080/00031305.2017.1375989) pour plus de conseils sur l'organisation des données. --- # Exemples de mauvaises habitudes: <br> .pull-left[ ![:scale 115%](images/Excel_csv_good_bad/excel_values.png) ] .pull-right[ ![:scale 115%](images/Excel_csv_good_bad/excel_notes.png) ] --- # Exemples de très mauvaises présentations .center[ ![:scale 90%](images/HorribleData.png)] --- # Préparer ses données dans R Il est possible de faire toute la préparation des données dans R. Les avantages sont : * On économise du temps pour les grosses bases de données * On préserve les données d'origine * On peut basculer entre les modes "long" et "large" très facilement (plus de détails plus tard) * Pour des informations complémentaires, consultez la page suivante : https://www.zoology.ubc.ca/~schluter/R/data/ --- class: inverse, center, middle # Écrire un script dans R --- # Les scripts R * Un script R c'est * un fichier texte contenant toutes les commandes nécessaires pour réaliser un projet. * Une fois écrit et enregistré, votre script R vous permettra d'apporter des changements et de refaire des analyses avec un minimum d'effort. * Sélectionnez simplement une commande et appuyez sur "Run" ou sur 'command-enter' (Mac) ou 'ctrl-enter' (PC). --- # Créer un script dans R .center[ ![:scale 80%](images/1_Create_an_R_script.png) ] --- # Écrire un script dans R .center[ ![:scale 90%](images/2_Create_an_R_script2.Mod_arrow.png) ] --- # Commandes & Commentaires Utilisez le symbole `#` pour insérer des commentaires au sein d'un script. Ceci indique à R d'ignorer tout ce qui se trouve à la suite du symbole `#` lors de l'exécution de commandes. ```r # Ceci est un commentaire pas une commande R! ``` --- # Commandes & Commentaires **Annoter son script est un bon moyen de** : * se rappeler ce que vous avez fait * dire aux collaborateurs ce que vous avez fait * favoriser une science reproductible .comment[Soyez aussi détaillé que possible !] --- # Entêtes de section Il est recommandé de commencer vos scripts avec un entête pour indiquer des infos importantes: nom du projet, auteur, date, version de R, etc. .center[ ![:scale 75%](images/3_Header.Mod_arrow.png) ] --- # Entêtes de section Sur R studio, Vous pouvez utiliser quatre symboles `#` de suite pour créer un entête de section. Par exemple : ```r #### Chargement du fichier de données #### ``` Cela vous permet de passer rapidement d'une section à l'autre et de masquer des sections. .center[ ![:scale 60%](images/4_Section_headings_Mod_arrow 2.png) ] --- # Nettoyage C'est une bonne habitude de maintenir son espace de travail propre en effaçant la mémoire de R à l'aide de `rm(list=ls())`. ```r rm(list = ls()) # Efface ce qui se trouve dans l'espace de travail ?rm ?ls ``` Cette commande permet d'éviter d'utiliser un vieux jeu de données qui serait resté dans l'espace de travail. --- # Nettoyage On peut tester cette commande en ajoutant des objets dans l'espace de travail pour mieux comprendre comment `rm(list=ls())` fonctionne. ```r A <-"Test" # On crée un objet "A". A <- "Test" # Utilisez des espaces - plus facile à lire A = "Test" # Note: il est recommandé d'utiliser "<-" pour l'assigment au lieu de "=" # Visualiser des objets en mémoire ls() # [1] "A" A # [1] "Test" # Nettoyer la mémoire rm(list=ls()) A # Error in eval(expr, envir, enclos): object 'A' not found ``` --- # Petit rappel important * R est prêt à exécuter une commande lorsque vous voyez le chevron `>` affiché dans la console. Si le chevron n'apparaît pas, c'est qu'une commande est incomplète. Appuyez sur 'ESC' pour sortir de cette commande. * R est sensible à la casse, i.e. `A` est différent de `a`. ```r a <- 10 A <- 5 a # [1] 10 A # [1] 5 rm(list=ls()) # On nettoie l'espace de travail à nouveau ! ``` --- class: inverse, center, middle # Charger, explorer et enregistrer des données --- # Télécharger les données Vous pouvez télécharger les données depuis : .center[https://github.com/QCBSRworkshops/workshop02/tree/main/pres-fr/data] Et le script depuis : .center[https://r.qcbs.ca/workshop02/book-fr/workshop02-script-fr.R] Enregistrez les fichiers dans le dossier où vous avez crée votre projet R. -- <br> .alert[NOTE] Il existe des données déjà disponibles sur R ```r # Liste complete de tous les données disponibles sur base R library(help = "datasets") ``` --- # Répertoire de travail Si vous n'utilisez pas un **projet RStudio**, vous devez indiquer à R le répertoire où se trouvent les fichiers de données afin de les charger. Pour voir quel répertoire R utilise : ```r getwd() ``` Si ce n'est pas le répertoire avec lequel vous souhaitez travailler, vous pouvez définir le vôtre à l'aide de: ```r setwd("C:/Users/mon_repertoire") ``` .comment[Il est recommandé de créer un projet RStudio et ne pas utiliser `setwd()` pour faciliter la reproducibilité] --- # Afficher le contenu du répertoire de travail La fonction `dir()` affiche le contenu du répertoire de travail. ```r dir() # [1] "assets" "data" "images" # [4] "pres-fr.Rproj" "qcbsR-fonts.css" "qcbsR-header.html" # [7] "qcbsR-macros.js" "qcbsR.css" "workshop02-pres-fr.Rmd" ``` Vous pouvez vérifier: * Si le fichier que vous voulez ouvrir se trouve dans le répertoire de travail * L'orthographe du nom du fichier (e.g. 'monfichier.csv' au lieu de 'MonFichier.csv') --- # Importer un jeu de données Utilisez la fonction `read.csv()` pour importer des données provenant d'un fichier .csv dans R. ```r CO2 <- read.csv("data/co2_good.csv", header=TRUE) ``` - Cette commande va créer un objet nommé `CO2` - Le nom du fichier est écrit entre guillemets (`'file'` ou `"file"`) - Si vous voulez charger un fichier d'un autre répertoire, vous devrez écrire l'extension complète: `read.csv("C:/Users/Mario/Downloads/co2_good.csv")` - `header = TRUE` permet de spécifier que la première ligne du fichier contient le nom des colonnes Il est aussi possible d’utiliser la fonction file.choose() pour charger un fichier de manière interactive. ```r CO2 <- read.csv(file.choose()) ``` --- # Importer un jeu de données Rappelez-vous que vous pouvez obtenir de l'aide pour une fonction avec `?` ```r ?read.csv ``` .alert[NOTE] Si vous utilisez un système d'exploitation en français ou un éditeur CSV, il est possible que vous deviez utiliser la fonction `read.csv2()` pour importer correctement un fichier. ```r ?read.csv2 ``` --- # Importer un jeu de données .center[ ![](images/5_Importing_data_Mod_arrow.png) ] Prenez note que RStudio montre maintenant le jeu de données CO2 dans votre **espace de travail**. L'espace de travail inclut tous les objets créés pendant la session R. --- # Visualiser les données R code | action ----------------- | ------------- `CO2` | Affiche le tableau de données complet dans la console `head(CO2)` | Affiche les premières lignes du tableau de données `tail(CO2)` | Affiche les dernières lignes du tableau de données `names(CO2)` | Affiche le nom des colonnes du tableau de données `attributes(CO2)` | Affiche les attributs du tableau de données `dim(CO2)` | Affiche la dimension du tableau de données `ncol(CO2)` | Affiche le nombre de colonnes du tableau de données `nrow(CO2)` | Affiche le nombre de lignes du tableau de données `summary(CO2)` | Calcule quelques statistiques de base sur les variables .small[.alert[NOTE] Ces fonctions sont aussi utilisés pour d'autres objets tels que `vector`, `matrix`, `list`, `array`, etc.] --- # Visualiser les données ```r str(CO2) # 'data.frame': 84 obs. of 5 variables: # $ Plant : chr "Qn1" "Qn1" "Qn1" "Qn1" ... # $ Type : chr "Quebec" "Quebec" "Quebec" "Quebec" ... # $ Treatment: chr "nonchilled" "nonchilled" "nonchilled" "nonchilled" ... # $ conc : int 95 175 250 350 500 675 1000 95 175 250 ... # $ uptake : num 16 30.4 34.8 37.2 35.3 39.2 39.7 13.6 27.3 37.1 ... ``` La fonction `str()` est très utile pour identifier le type/mode de chaque colonne. .small[Note : Le jeu de données `CO2` contient des mesures répétées d'absorption de CO2 prises sur 6 plantes du Québec et 9 plantes du Mississippi à différentes concentrations de CO2 ambiant. La moitié des plantes de chaque région a subi un traitement de refroidissement la veille du début de l'expérience.] --- # Visualiser les données Problèmes fréquents lors de l'importation des données : * Les facteurs apparaissent comme des chaînes de caractères (et vice versa) * Les facteurs ont trop de niveaux à cause d'une erreur de frappe * Les données numériques sont stockées sous forme de chaînes de caractères à cause d'une erreur de frappe --- # Exercice Chargez les données de nouveau en utilisant le script suivant : ```r CO2 <- read.csv("data/co2_good.csv", header = FALSE) ``` Vérifiez la structure des données avec la fonction `str()`. Quel est le problème ? -- .comment[N'oubliez pas de recharger les données avec l'argument `header=TRUE` avant de continuer.] --- # Rappel de l'atelier 1 : Accéder aux données Plusieurs façons d'extraire les données avec les crochets. Considérons un jeu de données nommé `mydata`. .center[ ![:scale 45%](images/Table_Reminder_from_Workshop_1_Accessing_data.png) ] ```r mydata[2,3] # Extrait la 2ème ligne / 3ème colonne mydata[1,] # Extrait la 1ère ligne mydata[,1] # Extrait la 1ère colonne mydata[,1][2] # [...] peut être utilisé récursivement mydata$Variable1 # Extrait la colonne "Variable1" ``` --- # Renommer les variables On peut renommer les variables (colonnes) dans R. ```r # Créer une copie du jeu de données qu'on pourra modifier CO2copy <- CO2 # names() donne les noms des variables présentes dans le jeu de données names(CO2copy) # [1] "Plant" "Type" "Treatment" "conc" "uptake" # Changer des noms anglais pour des noms français names(CO2copy) <- c("Plante", "Categorie", "Traitement", "conc", "absorption") names(CO2copy) # [1] "Plante" "Categorie" "Traitement" "conc" "absorption" ``` --- # Créer des nouvelles variables On peut facilement créer et produire des nouvelles variables. Par exemple, la fonction `paste()` permet la concaténation de chaînes de caractères et de variables. Consultez `?paste` et `?paste0`. Créer un ID unique pour les échantillons avec la fonction `paste0()` ```r # N'oubliez pas d'utiliser "" pour les chaînes de caractères CO2copy$uniqueID <- paste0(CO2copy$Plante, "_", CO2copy$Categorie, "_", CO2copy$Traitement) # Observer les résultats head(CO2copy$uniqueID) # [1] "Qn1_Quebec_nonchilled" "Qn1_Quebec_nonchilled" "Qn1_Quebec_nonchilled" # [4] "Qn1_Quebec_nonchilled" "Qn1_Quebec_nonchilled" "Qn1_Quebec_nonchilled" ``` --- # Créer des nouvelles variables On peut aussi créer des nouvelles variables à partir de chiffres et d'opérations mathématiques! ```r # Standardizer la variable "absorption" en valeurs relatives CO2copy$absorptionRel <- CO2copy$absorption/max(CO2copy$absorption) # Observer les résultats head(CO2copy$absorptionRel) # [1] 0.3516484 0.6681319 0.7648352 0.8175824 0.7758242 0.8615385 ``` --- # Sous-ensemble d'un data frame Il existe plusieurs façons d'en faire : ```r # On continue à travailler avec notre jeux de données CO2copy # Extraire un sous-ensemble par un nom de variable CO2copy[, c("Plante", "absorptionRel")] # Extraire un sous-ensemble de rangées CO2copy[1:50, ] ``` --- # Sous-ensemble d'un data frame ```r # Extraire les observations du traitement "nonchilled" CO2copy[CO2copy$Traitement == "nonchilled", ] # Extraire selon une condition numérique CO2copy[CO2copy$absorption >= 20, ] # Extraire selon plusieurs conditions numériques CO2copy[CO2copy$Traitement == "nonchilled" & CO2copy$absorption >= 20, ] # Nous avons fini de modifier le data frame CO2copy, effaçons-le rm(CO2copy) ``` Consultez [ici](https://stat.ethz.ch/R-manual/R-devel/library/base/html/Logic.html) pour voir les opérateurs logiques pouvant être utilisés pour extraire des sous-ensembles de données dans R. --- # Explorer les données Un bon moyen de commencer votre exploration des données consiste à regarder des statistiques de base sur votre jeu de données. Utilisez la fonction `summary()`. ```r summary(CO2) ``` C'est également utile pour repérer certaines erreurs que vous auriez peut-être manquées! --- # Explorer les données Vous pouvez également utiliser d'autres fonctions pour calculer des statistiques de base pour des parties spécifiques de votre trame de données. Essayons les fonctions `mean()`, `sd()` et `hist()` : ```r # Calculer la moyenne et l'écart type de la concentration, # et les assigner à de nouvelles variables meanConc <- mean(CO2$conc) sdConc <- sd(CO2$conc) ``` ```r # print() imprime une valeur donnée dans la console R print(paste("the mean of concentration is:", meanConc)) # [1] "the mean of concentration is: 435" print(paste("the standard deviation of concentration is:", sdConc)) # [1] "the standard deviation of concentration is: 295.924119222056" ``` --- # Explorer les données ```r # Créons un histogramme pour explorer la distribution de "uptake" hist(CO2$uptake) ``` <img src="workshop02-pres-fr_files/figure-html/unnamed-chunk-25-1.png" width="432" style="display: block; margin: auto;" /> --- # Explorer les données ```r # Créons un histogramme pour explorer la distribution de "uptake" hist(CO2$uptake, breaks = 40) # breaks permet de changer le nombre de classes ``` <img src="workshop02-pres-fr_files/figure-html/unnamed-chunk-26-1.png" width="432" style="display: block; margin: auto;" /> --- # La fonction `apply` La fonction `apply()` est utilisée pour appliquer une fonction à plusieurs colonnes en même temps. Utilisez ?apply pour en apprendre plus. ```r ?apply ``` Pour utiliser la fonction `apply()`, trois arguments doivent être spécifiés. Le premier argument est le jeu de données sur lequel on veut appliquer une fonction. Le deuxième argument spécifie si la fonction est appliquée aux lignes `(MARGIN = 1)` ou aux colonnes `(MARGIN = 2)`. Le dernier argument spécifie la fonction à appliquer. Par exemple : ```r # Calcule la moyenne des colonnes 4 et 5 du jeu de données CO2 apply(CO2[,4:5], MARGIN = 2, FUN = mean) # conc uptake # 435.0000 27.2131 ``` --- # Enregistrer son espace de travail ```r # Sauver l'espace de travail avec tous les objets save.image(file="data/co2_project_Data.RData") # Nettoyer l'espace de travail rm(list = ls()) # Charger tout ce qui se trouvait dans l'espace de travail load("data/co2_project_Data.RData") head(CO2) # cela fonctionne! :) ``` ``` # Plant Type Treatment conc uptake # 1 Qn1 Quebec nonchilled 95 16.0 # 2 Qn1 Quebec nonchilled 175 30.4 # 3 Qn1 Quebec nonchilled 250 34.8 # 4 Qn1 Quebec nonchilled 350 37.2 # 5 Qn1 Quebec nonchilled 500 35.3 # 6 Qn1 Quebec nonchilled 675 39.2 ``` --- # Exporter des données Pour enregistrer dans le répertoire de travail des données que vous avez créées ou modifiées dans R, utilisez la fonction `write.csv()`. ```r write.csv(CO2, file = "data/co2_new.csv") ``` `CO2` ![:faic](arrow-right) Nom de l'objet dans R `"co2_new.csv"` ![:faic](arrow-right) Nom du nouveau fichier à enregistrer --- # Défi ![:cube]() #### Utilisez vos données - Essayez de charger, explorer, et enregistrer vos propres données dans R .comment[ * Si ce n'est pas le cas, essayez de corriger vos données dans Excel. * Enregistrez vos données corrigées et ré-essayez de les ouvrir dans R. * Si vous n'avez pas de données, travaillez avec vos voisins * N'oubliez pas de nettoyer votre espace de travail ] --- class: inverse, center, middle # Réparer un jeu de données --- # Réparer un jeu de données "endommagé" Charger vos données peut être plus difficile que vous ne le pensez! Les jeux de données peuvent être désordonnés et incompatibles entre certains systèmes (Mac, Windows) ou entre ordinateurs. Pratiquons-nous à réparer certains problèmes communs. --- # Défi ![:cube]() Lire le ficher `co2_broken.csv` ```r CO2 <- read.csv("data/co2_broken.csv") head(CO2) # C'est le chaos! # NOTE..It.rain.a.lot.in.Quebec.during.sampling due.to.excessive X # 1 falling on my notebook numerous values can't be read rain NA NA # 2 Plant\tType\tTreatment\tconc\tuptake NA NA # 3 Qn1\tQuebec\tnonchilled\t95\t16 NA NA # 4 Qn1\tQuebec\tnonchilled\t175\t30.4 NA NA # 5 Qn1\tQuebec\tnonchilled\t250\tcannot_read_notes NA NA # 6 Qn1\tQuebec\tnonchilled\t350\t37.2 NA NA # X.1 X.2 X.3 # 1 NA NA NA # 2 NA NA NA # 3 NA NA NA # 4 NA NA NA # 5 NA NA NA # 6 NA NA NA ``` --- # Défi ![:cube]() Voici quelques fonctions qui peuvent vous aider : * `read.csv()` - examinez les options permettant de charger un fichier .csv * `head()` - montre les premières lignes * `str()` - structure de données * `class()` - classe de l'objet * `unique()` - observations uniques * `levels()` - niveaux d'un facteur * `which()` - pose une question sur votre bloc de données * `droplevels()` - supprime les niveaux indésirables après avoir déduit les facteurs .alert[Indice] Il y a quatre problèmes avec ce jeu de données! --- # Jeu de données "endommagé" .alert[ERREUR 1] Les données sont contenues dans une seule colonne ```r head(CO2) # NOTE..It.rain.a.lot.in.Quebec.during.sampling due.to.excessive X # 1 falling on my notebook numerous values can't be read rain NA NA # 2 Plant\tType\tTreatment\tconc\tuptake NA NA # 3 Qn1\tQuebec\tnonchilled\t95\t16 NA NA # 4 Qn1\tQuebec\tnonchilled\t175\t30.4 NA NA # 5 Qn1\tQuebec\tnonchilled\t250\tcannot_read_notes NA NA # 6 Qn1\tQuebec\tnonchilled\t350\t37.2 NA NA # X.1 X.2 X.3 # 1 NA NA NA # 2 NA NA NA # 3 NA NA NA # 4 NA NA NA # 5 NA NA NA # 6 NA NA NA ``` --- # Jeu de données "endommagé" .alert[ERREUR 1] - Solution * Importez les données de nouveau, en spécifiant comment chaque valeur est séparée. * L'argument `sep` indique à R quel type de caractère sépare les valeurs sur chaque ligne. * Ici, une tabulation sépare les valeurs au lieu d'une virgule. ```r CO2 <- read.csv("data/co2_broken.csv", sep = "") ``` --- # Jeu de données "endommagé" .alert[ERREUR 2] Les données ne commencent pas avant la 3ème ligne. Les entêtes de colonnes sont remplacés par des notes. ```r head(CO2) # NOTE. It rain a lot in. Quebec during # 1 falling on my notebook numerous values can't be # 2 Plant Type Treatment conc uptake # 3 Qn1 Quebec nonchilled 95 16 # 4 Qn1 Quebec nonchilled 175 30.4 # 5 Qn1 Quebec nonchilled 250 cannot_read_notes # 6 Qn1 Quebec nonchilled 350 37.2 # sampling. due to excessive X.... # 1 read rain,,,, NA NA NA # 2 NA NA NA # 3 NA NA NA # 4 NA NA NA # 5 NA NA NA # 6 NA NA NA ``` --- # Jeu de données "endommagé" .alert[ERREUR 2] - Solution Pour régler ce problème, vous devez indiquer à R de sauter les deux premières lignes avec l'argument "skip". ```r CO2 <- read.csv("data/co2_broken.csv", sep = "", skip = 2) head(CO2) # Plant Type Treatment conc uptake # 1 Qn1 Quebec nonchilled 95 16 # 2 Qn1 Quebec nonchilled 175 30.4 # 3 Qn1 Quebec nonchilled 250 cannot_read_notes # 4 Qn1 Quebec nonchilled 350 37.2 # 5 Qn1 Quebec nonchilled 500 35.3 # 6 Qn1 Quebec nonchilled cannot_read_notes 39.2 ``` --- # Jeu de données "endommagé" .alert[ERREUR 3] Les variables `conc` et `uptake` sont considérées comme des facteurs au lieu de nombres, car il y a du texte dans ces colonnes. ```r str(CO2) # 'data.frame': 84 obs. of 5 variables: # $ Plant : chr "Qn1" "Qn1" "Qn1" "Qn1" ... # $ Type : chr "Quebec" "Quebec" "Quebec" "Quebec" ... # $ Treatment: chr "nonchilled" "nonchilled" "nonchilled" "nonchilled" ... # $ conc : chr "95" "175" "250" "350" ... # $ uptake : chr "16" "30.4" "cannot_read_notes" "37.2" ... class(CO2$conc) # [1] "character" ``` ```r unique(CO2$conc) # [1] "95" "175" "250" # [4] "350" "500" "cannot_read_notes" # [7] "1000" "675" ``` --- # `?read.csv` ![:scale 80%](images/read_table_help1.png) ![:scale 80%](images/read_table_help2.png) --- # Jeu de données "endommagé" .alert[ERREUR 3] - Solution Indiquez à R que tous les éléments NA, "na" et "cannot_read_notes" doivent être considérés comme des NA. Ensuite, comme toutes les autres valeurs de ces colonnes sont des nombres, `conc` et` uptake` seront chargés sous forme numérique / entier. ```r CO2 <- read.csv("data/co2_broken.csv", sep = "", skip = 2, na.strings = c("NA", "na", "cannot_read_notes")) str(CO2) # 'data.frame': 84 obs. of 5 variables: # $ Plant : chr "Qn1" "Qn1" "Qn1" "Qn1" ... # $ Type : chr "Quebec" "Quebec" "Quebec" "Quebec" ... # $ Treatment: chr "nonchilled" "nonchilled" "nonchilled" "nonchilled" ... # $ conc : int 95 175 250 350 500 NA 1000 95 175 250 ... # $ uptake : num 16 30.4 NA 37.2 35.3 39.2 39.7 13.6 27.3 37.1 ... ``` --- # Jeu de données "endommagé" .alert[ERREUR 4] En réalité, il y a seulement 2 traitements (chilled & non chilled), mais des erreurs d'orthographe créent 2 autres niveaux de traitement. ```r str(CO2) ``` ```r levels(CO2$Treatment) # NULL unique(CO2$Treatment) # [1] "nonchilled" "nnchilled" "chilled" "chiled" ``` --- # Jeu de données "endommagé" .alert[ERREUR 4] - Solution ```r # Vous pouvez utiliser la fonction which() afin de trouver # les lignes avec l'erreur 'nnchilled' # Cette commande nous indique que l'erreur se trouve à la ligne 10 which(CO2$Treatment == "nnchilled") # [1] 10 11 15 # Vous pouvez corriger l'erreur par indexation (voir atelier 1) : CO2$Treatment[10] <- "nonchilled" # Vous pouvez faire ces deux étapes en une seule commande : CO2$Treatment[which(CO2$Treatment == "nnchilled")] <- "nonchilled" # Faisons la même chose pour 'chiled' : CO2$Treatment[which(CO2$Treatment == "chiled")] <- "chilled" ``` --- # Jeu de données "endommagé" .alert[ERREUR 4] - Solution Après avoir réparé les facteurs, il faut enlever les niveaux de facteur non utilisés Sinon : ```r boxplot(uptake ~ Treatment, data = CO2) ``` <img src="workshop02-pres-fr_files/figure-html/unnamed-chunk-43-1.png" width="360" style="display: block; margin: auto;" /> --- # Jeu de données "endommagé" .alert[ERREUR 4] - Solution ```r CO2 <- droplevels(CO2) str(CO2) # 'data.frame': 84 obs. of 5 variables: # $ Plant : chr "Qn1" "Qn1" "Qn1" "Qn1" ... # $ Type : chr "Quebec" "Quebec" "Quebec" "Quebec" ... # $ Treatment: chr "nonchilled" "nonchilled" "nonchilled" "nonchilled" ... # $ conc : int 95 175 250 350 500 NA 1000 95 175 250 ... # $ uptake : num 16 30.4 NA 37.2 35.3 39.2 39.7 13.6 27.3 37.1 ... ``` .pull-left[ ```r boxplot(uptake ~ Treatment, data = CO2) ``` ] .pull-right[ <img src="workshop02-pres-fr_files/figure-html/unnamed-chunk-46-1.png" width="360" style="display: block; margin: auto;" /> ] --- class: inverse, center, middle # Bienvenue dans le monde de tidyverse ! --- # Qu'est ce que Tidyverse? [`Tidyverse`](https://www.tidyverse.org/) est un ensemble de packages conçus pour la manipulation de données en science. `Tidyverse` contient des outils plus efficaces et conviviales très utiles pour toutes sortes d’analyses. Tous les packages inclus dans `tidyverse` sont automatiquement installés lors de l'installation de `tidyverse` : `install.packages("tidyverse")` <br> <br> Par exemple : * [`tidyr`](https://tidyr.tidyverse.org/): réorganiser les tables de données * [`dplyr`](https://dplyr.tidyverse.org/): manipuler les données * [`maggritr`](https://magrittr.tidyverse.org/): lier plusieurs opérations * [`ggplot2`](https://ggplot2.tidyverse.org/): faire des graphiques * [`readr`](https://readr.tidyverse.org/): lire les données (plus rapide !) * [`lubridate`](https://lubridate.tidyverse.org/): manipuler des données de dates et de temps * [et plus !](https://www.tidyverse.org/packages/) --- class: inverse, center, middle # Manipulation de données avec ## tidyr, dplyr, magrittr --- # `tidyr` pour réorganiser ses données ```r library(tidyr) ``` .center[ ![:scale 40%](images/tidyr_logo.png) ] --- # Format de données .pull-left[ **Format large (wide)** .small[Un data frame en format large contient une colonne pour chaque variable ou facteur] ``` # Species DHP Haut # 1 Chene 12 56 # 2 Orme 20 85 # 3 Frene 13 55 ``` ] .pull-right[ **Format long** .small[Un data frame en format long contient une colonne par variable, où chaque ligne est une observation] ``` # Species dimension cm # 1 Chene DHP 12 # 2 Orme DHP 20 # 3 Frene DHP 13 # 4 Chene Haut 56 # 5 Orme Haut 85 # 6 Frene Haut 55 ``` ] ------------ `ggplot2` peut utiliser le format large pour des visualisations simples, mais des visualisations plus complexes requièrent le format long. `dplyr`, `lm()`, `glm()`, `gam()` nécessitent le format long. --- # Manipuler vos données Le paquet `tidyr` permet de manipuler la structure d'un data frame en préservant les informations d'origine `pivot_longer()` ![:faic](arrow-right) "rassembler" les données (large -> long) `pivot_wider()` ![:faic](arrow-right) "disperser" les données (long -> large) .center[ ![scale:90%](images/gather-spread.png)] --- # Installation du paquet `tidyr` ```r install.packages("tidyr") library(tidyr) ``` --- # Rassembler les colonnes en lignes `pivot_longer(data, cols, names_to, values_to, ...)` <span style="font-size: 21px;"> - `data` le jeu de données (e.g. 'large') - `cols` les colonnes qu'on veut empiler dans le jeu de données (e.g. `DHP`, `Haut`) - `names_to` le nom de la nouvelle colonne spécifiant la variable mesurée (e.g. `dimension`) - `values_to` le nom de la nouvelle colonne spécifiant la mesure associée (e.g. `cm`) </span> --- # Rassembler avec `pivot_longer()` ```r large <- data.frame(Species = c("Chene", "Orme", "Frene"), DHP = c(12, 20, 13), Haut = c(56, 85, 55)) large # Species DHP Haut # 1 Chene 12 56 # 2 Orme 20 85 # 3 Frene 13 55 ``` ```r long <- pivot_longer(data = large, cols = c("DHP", "Haut"), names_to = "dimension", values_to = "cm") long # # A tibble: 6 × 3 # Species dimension cm # <chr> <chr> <dbl> # 1 Chene DHP 12 # 2 Chene Haut 56 # 3 Orme DHP 20 # 4 Orme Haut 85 # 5 Frene DHP 13 # 6 Frene Haut 55 ``` --- # Disperser avec les lignes en colonnes `pivot_wider(data, names_from, values_from, ...)` <span style="font-size: 21px;"> - `data` le jeu de données (e.g. `long`) - `names_from` nom de la colonne contenant les noms des variables (e.g. `dimension`) - `values_from` nom de la colonne contenant les mesures associées aux variables (e.g. `cm`) </span> --- # Disperser avec `pivot_wider()` ```r long # # A tibble: 6 × 3 # Species dimension cm # <chr> <chr> <dbl> # 1 Chene DHP 12 # 2 Chene Haut 56 # 3 Orme DHP 20 # 4 Orme Haut 85 # 5 Frene DHP 13 # 6 Frene Haut 55 ``` ```r large2 <- pivot_wider(data = long, names_from = "dimension", values_from = "cm") large2 # # A tibble: 3 × 3 # Species DHP Haut # <chr> <dbl> <dbl> # 1 Chene 12 56 # 2 Orme 20 85 # 3 Frene 13 55 ``` --- # La structure `tibble` pour des tables de données `Tibble` est un format alternatif et plus pratique que celui d'un data frame. L'utilisation d'un tribble favorise de bonnes habitudes de programmation. Par exemple, il ne change pas une variable de chaine de caractère en facteur. ```r tibble(x = 1:3, y = c("a","b","c")) # # A tibble: 3 × 2 # x y # <int> <chr> # 1 1 a # 2 2 b # 3 3 c ``` --- # La structure `tibble` pour des tables de données En plus, `tibble` simplifie l'utilisation de lists imbriqués dans la table de données. Exemple: ```r tibble(x = 1:3, y = list(1:5, 1:10, 1:20)) # # A tibble: 3 × 2 # x y # <int> <list> # 1 1 <int [5]> # 2 2 <int [10]> # 3 3 <int [20]> ``` Toutes les fonctions appliquées sur un data frame peuvent aussi être utilisées sur un tibble --- # `separate()` des colonnes .center[ ![](images/separate.png) ] `separate(data, col, into, sep)` - `data` ![:faic](arrow-right) Un data frame (e.g. `long`) - `col` ![:faic](arrow-right) Nom de la colonne que nous voulons séparer - `into` ![:faic](arrow-right) Nom des nouvelles colonnes crées par la séparation - `sep` ![:faic](arrow-right) Caractère qui indique où séparer le contenu --- # Utiliser `separate()` Créons un jeu de données fictif sur les poissons et le zooplancton : ```r set.seed(8) degat <- data.frame(id = 1:4, trt = sample(rep(c('control', 'culture'), each = 2)), zooplancton.T1 = runif(4), poisson.T1 = runif(4), zooplancton.T2 = runif(4), poisson.T2 = runif(4)) degat # id trt zooplancton.T1 poisson.T1 zooplancton.T2 poisson.T2 # 1 1 culture 0.7189275 0.64449114 0.544962116 0.2644589 # 2 2 culture 0.2908734 0.45704489 0.138224346 0.2765322 # 3 3 control 0.9322698 0.08930101 0.927812252 0.5211070 # 4 4 control 0.7691470 0.43239137 0.001301721 0.2236889 ``` --- # Utiliser `separate()` On peut commencer par convertir ce jeu de données vers le format long. ```r degat.long <- pivot_longer(degat, names_to = "taxa", cols = c("zooplancton.T1", "poisson.T1", "zooplancton.T2", "poisson.T2")) head(degat.long) # # A tibble: 6 × 4 # id trt taxa value # <int> <chr> <chr> <dbl> # 1 1 culture zooplancton.T1 0.719 # 2 1 culture poisson.T1 0.644 # 3 1 culture zooplancton.T2 0.545 # 4 1 culture poisson.T2 0.264 # 5 2 culture zooplancton.T1 0.291 # 6 2 culture poisson.T1 0.457 ``` --- # Utiliser `separate()` Ensuite, on veut séparer les 2 temps d'échantillonnage (T1 et T2) dans la colonne "taxa" en utilisant le point comme caractère de séparation ```r degat.long.sep <- separate(degat.long, taxa, into = c("especes", "temps"), sep = "\\.") head(degat.long.sep) # # A tibble: 6 × 5 # id trt especes temps value # <int> <chr> <chr> <chr> <dbl> # 1 1 culture zooplancton T1 0.719 # 2 1 culture poisson T1 0.644 # 3 1 culture zooplancton T2 0.545 # 4 1 culture poisson T2 0.264 # 5 2 culture zooplancton T1 0.291 # 6 2 culture poisson T1 0.457 ``` .small[ .comment[ L'argument `sep = " \\."` indique à R de scinder la chaîne de caractères autour du point (.). Nous ne pouvons pas écrire directement `sep = "."` car il s’agit d’une expression régulière qui correspond à n’importe quel caractère (un joker). ]] --- # Récapitulatif: `tidyr` `tidyr` est un paquet qui réorganise la structure de jeux de données. Convertir de format large en format long à l'aide de `pivot_longer()` Convertir de format long en format large à l'aide de `pivot_wider()` Séparer et regrouper des colonnes à l'aide de `separate()` et de son inverse `unite()` [Voici un aide-mémoire (en anglais) pour faciliter la manipulation de jeux de données avec tidyr et dplyr](https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf) --- # Défi #1 ![:cube]() Réorganisez le jeu de données `airquality` en format long (en rassemblant toutes les colonnes sauf "Month" et "Day"). ```r ?airquality data(airquality) ``` --- # Solution #1 Réorganisez le jeu de données `airquality` en format long (en rassemblant toutes les colonnes sauf "Month" et "Day"). ```r air.long <- pivot_longer(airquality, cols = c("Ozone", "Solar.R", "Wind", "Temp"), names_to = c("variable")) head(air.long) # # A tibble: 6 × 4 # Month Day variable value # <int> <int> <chr> <dbl> # 1 5 1 Ozone 41 # 2 5 1 Solar.R 190 # 3 5 1 Wind 7.4 # 4 5 1 Temp 67 # 5 5 2 Ozone 36 # 6 5 2 Solar.R 118 ``` --- # Défi #2 ![:cube]() Convertissez-le en format large pour retrouver le format original de `airquality` --- # Solution #2 Convertissez-le en format large pour retrouver le format original de `airquality` ```r air.wide <- pivot_wider(air.long, values_from = "value", names_from = "variable") head(air.wide) # # A tibble: 6 × 6 # Month Day Ozone Solar.R Wind Temp # <int> <int> <dbl> <dbl> <dbl> <dbl> # 1 5 1 41 190 7.4 67 # 2 5 2 36 118 8 72 # 3 5 3 12 149 12.6 74 # 4 5 4 18 313 11.5 62 # 5 5 5 NA NA 14.3 56 # 6 5 6 28 NA 14.9 66 ``` --- # Manipulation avec `dplyr` .center[ ![:scale 50%](images/dplyr_logo.png)] --- # Introduction à `dplyr` La mission de `dplyr` est de simplifier nos tâches de manipulation. - Package contenant un ensemble de fonctions (ou *verbes*) pour la manipulation de données, telles que le filtrage des lignes, la sélection de colonnes spécifiques, le réorganisation des lignes, l'ajout de nouvelles colonnes et la synthèse des données; - Fonctions simples et intuitives; - Rapide et efficace avec les grands jeux de données; - Peut s’interfacer avec des bases de données externes et traduire votre code R en requêtes SQL Certaines fonctions de base dans R ressemblent à des fonctions dans `dplyr`: `split()`, `subset()`, `apply()`, `sapply()`, `lapply()`, `tapply()` et `aggregate()` --- # Introduction à `dplyr` Commençons par installer et charger le paquet `dplyr` ```r library(dplyr) ``` --- # Fonctions de bases de `dplyr` Voici les 4 *verbes* principaux qui permettent d'exécuter les manipulations les plus communes: * `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 une nouvelle colonne de données (ou transforme une colonne existante) --- # `select()` - Sélection de colonnes .center[![:scale 60%](images/select.png)] `select(data, ...)` * `data` : le jeu de données * `...` : noms ou positions de colonnes, ou expressions complexes (séparés par des virgules pour désigner les colonnes que l'on veut sélectionner Examples : ```r select(données, colonne1, colonne2) # sélectionne colonne1 et colonne2 select(données, c(2:4,6) # sélectionne les colonnes 2 à 4, plus la 6ème colonne select(données, -colonne1) # sélectionne toutes les colonnes sauf la 1ère select(données, start_with(x.)) # sélectionne les colonnes ayant un nom qui # commence par "x." ``` --- # `select()` - Sélection de colonnes .center[![:scale 70%](images/select.helper.png)] --- # `select()` - Sélection de colonnes Par exemple, si on analyse la variation de la variable Ozone avec le temps. ```r 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 ``` --- # `filter()` - sélection de lignes Pour extraire un sous-ensemble de rangées selon une condition, on peut utiliser la fonction `filter()` avec la syntaxe suivante: `filter(dataframe, propostion logique 1, propostion logique 2, ...)` <br> .center[![:scale 90%](images/filter.png)] .center[![:scale 90%](images/logic.helper.png)] --- # `filter()` - sélection de lignes Par exemple, si on s'intéresse aux périodes de canicules du mois d'août dans le jeu de données `airquality` ```r aout <- filter(airquality, Month == 8, Temp >= 90) # ou 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 ``` --- # Ordonner des lignes avec `arrange()` Réordonne les lignes selon une ou plusieurs colonnes, par défaut en ordre croissant `arrange(données, variable1, variable2, ...)` On peut également réordonner les lignes en ordre décroissant en utilisant la fonction `desc()` à l'intérieur de la fonction `arrange()` `arrange(data, variable1, desc(variable2), ...)` --- # Ordonner des lignes avec `arrange()` Example : 1) Commençons par créer une version désordonnée de `airquality`: ```r air_degat <- sample_frac(airquality, 1) head(air_degat) # Ozone Solar.R Wind Temp Month Day # 1 23 115 7.4 76 8 18 # 2 28 273 11.5 82 8 13 # 3 8 19 20.1 61 5 9 # 4 135 269 4.1 84 7 1 # 5 23 299 8.6 65 5 7 # 6 30 322 11.5 68 5 19 ``` --- # Ordonner des lignes avec `arrange()` Example : 2) Maintenant, on réarrange le data frame en ordre chronologique, soit en ordre croissant selon `Month` et ensuite selon `Day` ```r 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 ``` .comment[Essayez `arrange(air_mess, Day, Month)` et voyez la différence.] --- # `mutate()` - Créer de nouvelles colonnes On peut utiliser la fonction `mutate()` pour créer et transformer des variables. `mutate(data, newVar1 = expression1, newVar2 = expression2, ...)` .center[ ![](images/mutate.png) ] --- # `mutate()` - Créer de nouvelles colonnes Par exemple, on veut transformer la variable température `Temp` de degrés Fahrenheit vers degrés Celsius ```r 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 ``` --- # `magrittr` Habituellement, la manipulation de données nécessite plusieurs étapes, le package `magrittr` propose l'opérateur `%>%` (*pipe operator*) qui nous permet de lier plusieurs opérations. .center[ ![:scale 40%](images/magrittr.png)] --- # `magrittr` Commençons par installer et charger le paquet : ```r library(magrittr) ``` --- # `magrittr` 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és Celsius. On peut créer ce data frame en combinant 2 *verbes* de dplyr ```r juin_C <- mutate(filter(airquality, Month == 6), Temp_C = (Temp-32)*(5/9)) ``` .comment[Plus on ajoute des opérations, plus ce code deviendra illisible. Mais, le faire étape par étape serait redondant et écrirait de nombreux objets dans l'espace de travail.] --- # `magrittr` Au lieu d'envelopper toutes les fonctions, on peut écrire les opérations en ordre d'exécutions et les relier à l'aide du *pipe* %>% : ```r juin_C <- airquality %>% filter(Month == 6) %>% mutate(Temp_C = (Temp-32)*(5/9)) ``` Avantages : * le code est moins redondant * le code est facile à lire et à écrire parce que les fonctions sont exécutées dans l'ordre --- # `dplyr::group_by` et `dplyr::summarise` Les verbes `dplyr` que nous avons appris dans cet atelier deviennent particulièrement puissants quand ils sont reliés par le "pipe" (%>%). Les fonctions `dplyr` suivantes nous permettent 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’agrégation et de sommaire: `group_by()` ![:faic](arrow-right) regrouper le jeu de données par un facteur pour les opérations en aval (comme `summarise()`) `summarise()` ![:faic](arrow-right) 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()`) --- # `dplyr` - Séparer-Appliquer-Combiner La fonction `group_by` est la base de la stratégie Séparer-Appliquer-Combiner .center[ ![](images/split-apply-combine.png) ] --- # `dplyr` - Séparer-Appliquer-Combiner .center[ ![:scale 70%](images/summarise.png) ] --- # `dplyr` - Séparer-Appliquer-Combiner Utilisons ces deux fonctions pour générer un sommaire du jeu de données `airquality` qui montre la température moyenne et l'écart type pour chaque mois: ```r mois_moy <- airquality %>% group_by(Month) %>% summarise(mean_temp = mean(Temp), sd_temp = sd(Temp)) mois_moy # # A tibble: 5 × 3 # Month mean_temp sd_temp # <int> <dbl> <dbl> # 1 5 65.5 6.85 # 2 6 79.1 6.60 # 3 7 83.9 4.32 # 4 8 84.0 6.59 # 5 9 76.9 8.36 ``` --- # Défi - `dplyr` et `magrittr` ![:cube]() 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" `%>%`. ```r ## ?ChickWeight data(ChickWeight) ``` --- # Solution 1. Utilisez `group_by()` pour grouper le jeu de données `ChickWeight` 2. Utilisez `summarise()` pour calculer la gain de poids par groupe ```r mass_diff <- ChickWeight %>% group_by(Chick) %>% summarise(mass_diff = max(weight) - min(weight)) head(mass_diff) # # A tibble: 6 × 2 # Chick mass_diff # <ord> <dbl> # 1 18 4 # 2 16 16 # 3 15 27 # 4 13 55 # 5 9 58 # 6 20 76 ``` --- # NINJA Défi - `dplyr` et `magrittr` ![:cube]() <br> - En utilisant le jeu de données `ChickWeight`, créez un tableau sommaire qui indique 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 la "pipe" `%>%`. <br> .alert[Indice] les fonctions `first()` et `last()` pourraient s'avérer utiles --- # Solution ninja ```r diet_mass <- ChickWeight %>% group_by(Diet, Chick) %>% summarise(gain_masse = last(weight) - first(weight)) %>% summarise(gain_moyen = mean(gain_masse)) diet_mass # # A tibble: 4 × 2 # Diet gain_moyen # <fct> <dbl> # 1 1 115. # 2 2 174 # 3 3 230. # 4 4 188. ``` --- # Défi R base ![:cube]() Maintenant essayez de refaire le même exercice mais **seulement avec les fonctions de bases de R Prenez note qu'il existe plusieurs solutions. .alert[Indice]: Les fonction `?aggregate()` ou `?by()` pourraient s'avérer utiles. --- # Défi R base - Solution ```r mass_diff_rbase <- aggregate(weight ~ Chick, data = ChickWeight, FUN = function(x) weight_diff = max(x) - min(x)) names(mass_diff_rbase) <- c("Chick", "weight_diff") ``` ```r # Est ce que les deux résultats sont identiques (c-a-d avec et sans dplyr) table(mass_diff_rbase == as.data.frame(mass_diff)) # # TRUE # 100 ``` --- # Fusionner des tableaux de données avec dplyr En plus des fonctions que nous avons explorées aujourd'hui, `dplyr` offre d'autres fonctions forts utiles nous permettant de fusionner des tableau de données, avec une syntaxe relativement simple : - `left_join()` - `right_join()` - `inner_join()` - `anti_join()` Ces fonctions vont au-delà du matériel d'introduction dans cet atelier, mais ils offrent des fonctionnalités pouvant être très utiles pour des manipulations de données plus complexes. --- # Ressources supplémentaires [Pour en savoir plus sur dplyr](http://r4ds.had.co.nz/transform.html) [dplyr et tidyr anti-sèche](https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf) --- class: inverse, center, bottom # Merci pour votre participation! :) ![:scale 50%](images/qcbs_logo.png)