+ - 0:00:00
Notes for current slide
Notes for next slide

Atelier 2: Charger et manipuler des données

Série d’ateliers R du CSBQ

Centre de la science de la biodiversité du Québec

1 / 121

À propos de cet atelier

badge badge badge badge

2 / 121

Packages requis


install.packages(c('dplyr', 'tidyr', 'magrittr'))
3 / 121

Objectifs d'apprentissage


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
4 / 121

Créer un projet RStudio


5 / 121

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.

6 / 121

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).

7 / 121

Un projet = un dossier

Organisez vos fichiers !

8 / 121

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

9 / 121

Bien nommer les fichiers

Évitez d’utiliser des espaces, des accents ou des caractères spéciaux pour vos noms

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 !)

Oui:

  • rawDatasetAgo2017.csv
  • co2_concentrations_QB.csv
  • 01_figIntro.R
10 / 121

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

Bien !

  • Measurements
  • SpeciesNames
  • Site

Pas bien !

  • a
  • 3
  • supernomunpeutroplong



Regardez le guide tidyverse pour plus de conseils.

11 / 121

Conseils pour préparer les données

  • 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!
  • É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!



Lire le paper de Broman & Woo (2017) pour plus de conseils sur l'organisation des données.

12 / 121

Exemples de mauvaises habitudes:


13 / 121

Exemples de très mauvaises présentations

14 / 121

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/
15 / 121

Écrire un script dans R

16 / 121

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).
17 / 121

Créer un script dans R

18 / 121

Écrire un script dans R

19 / 121

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.

# Ceci est un commentaire pas une commande R!
20 / 121

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

Soyez aussi détaillé que possible !

21 / 121

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.

22 / 121

Entêtes de section

Sur R studio, Vous pouvez utiliser quatre symboles # de suite pour créer un entête de section.

Par exemple :

#### Chargement du fichier de données ####

Cela vous permet de passer rapidement d'une section à l'autre et de masquer des sections.

23 / 121

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()).

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.

24 / 121

Nettoyage

On peut tester cette commande en ajoutant des objets dans l'espace de travail pour mieux comprendre comment rm(list=ls()) fonctionne.

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
25 / 121

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.
a <- 10
A <- 5
a
# [1] 10
A
# [1] 5
rm(list=ls()) # On nettoie l'espace de travail à nouveau !
26 / 121

Charger, explorer et enregistrer des données

27 / 121

Télécharger les données

Vous pouvez télécharger les données depuis :

https://github.com/QCBSRworkshops/workshop02/tree/main/pres-fr/data

Et le script depuis :

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.

28 / 121

Télécharger les données

Vous pouvez télécharger les données depuis :

https://github.com/QCBSRworkshops/workshop02/tree/main/pres-fr/data

Et le script depuis :

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.


NOTE Il existe des données déjà disponibles sur R

# Liste complete de tous les données disponibles sur base R
library(help = "datasets")
29 / 121

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 :

getwd()

Si ce n'est pas le répertoire avec lequel vous souhaitez travailler, vous pouvez définir le vôtre à l'aide de:

setwd("C:/Users/mon_repertoire")

Il est recommandé de créer un projet RStudio et ne pas utiliser setwd() pour faciliter la reproducibilité

30 / 121

Afficher le contenu du répertoire de travail

La fonction dir() affiche le contenu du répertoire de travail.

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')
31 / 121

Importer un jeu de données

Utilisez la fonction read.csv() pour importer des données provenant d'un fichier .csv dans 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.

CO2 <- read.csv(file.choose())
32 / 121

Importer un jeu de données

Rappelez-vous que vous pouvez obtenir de l'aide pour une fonction avec ?

?read.csv

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.

?read.csv2
33 / 121

Importer un jeu de données

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.

34 / 121

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

NOTE Ces fonctions sont aussi utilisés pour d'autres objets tels que vector, matrix, list, array, etc.

35 / 121

Visualiser les données

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.

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.

36 / 121

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
37 / 121

Exercice

Chargez les données de nouveau en utilisant le script suivant :

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 ?

38 / 121

Exercice

Chargez les données de nouveau en utilisant le script suivant :

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 ?

N'oubliez pas de recharger les données avec l'argument header=TRUE avant de continuer.

39 / 121

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.

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"
40 / 121

Renommer les variables

On peut renommer les variables (colonnes) dans 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"
41 / 121

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()

# 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"
42 / 121

Créer des nouvelles variables

On peut aussi créer des nouvelles variables à partir de chiffres et d'opérations mathématiques!

# 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
43 / 121

Sous-ensemble d'un data frame

Il existe plusieurs façons d'en faire :

# 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, ]
44 / 121

Sous-ensemble d'un data frame

# 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 pour voir les opérateurs logiques pouvant être utilisés pour extraire des sous-ensembles de données dans R.

45 / 121

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().

summary(CO2)

C'est également utile pour repérer certaines erreurs que vous auriez peut-être manquées!

46 / 121

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() :

# Calculer la moyenne et l'écart type de la concentration,
# et les assigner à de nouvelles variables
meanConc <- mean(CO2$conc)
sdConc <- sd(CO2$conc)
# 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"
47 / 121

Explorer les données

# Créons un histogramme pour explorer la distribution de "uptake"
hist(CO2$uptake)

48 / 121

Explorer les données

# Créons un histogramme pour explorer la distribution de "uptake"
hist(CO2$uptake, breaks = 40) # breaks permet de changer le nombre de classes

49 / 121

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.

?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 :

# 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
50 / 121

Enregistrer son espace de travail

# 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
51 / 121

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().

write.csv(CO2, file = "data/co2_new.csv")

CO2 Nom de l'objet dans R

"co2_new.csv" Nom du nouveau fichier à enregistrer

52 / 121

Défi

Utilisez vos données

  • Essayez de charger, explorer, et enregistrer vos propres données dans R
  • 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

53 / 121

Réparer un jeu de données

54 / 121

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.

55 / 121

Défi

Lire le ficher co2_broken.csv

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
56 / 121

Défi

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

Indice Il y a quatre problèmes avec ce jeu de données!

57 / 121

Jeu de données "endommagé"

ERREUR 1

Les données sont contenues dans une seule colonne

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
58 / 121

Jeu de données "endommagé"

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.
CO2 <- read.csv("data/co2_broken.csv", sep = "")
59 / 121

Jeu de données "endommagé"

ERREUR 2

Les données ne commencent pas avant la 3ème ligne. Les entêtes de colonnes sont remplacés par des notes.

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
60 / 121

Jeu de données "endommagé"

ERREUR 2 - Solution

Pour régler ce problème, vous devez indiquer à R de sauter les deux premières lignes avec l'argument "skip".

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
61 / 121

Jeu de données "endommagé"

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.

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"
unique(CO2$conc)
# [1] "95" "175" "250"
# [4] "350" "500" "cannot_read_notes"
# [7] "1000" "675"
62 / 121

?read.csv

63 / 121

Jeu de données "endommagé"

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 etuptake seront chargés sous forme numérique / entier.

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 ...
64 / 121

Jeu de données "endommagé"

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.

str(CO2)
levels(CO2$Treatment)
# NULL
unique(CO2$Treatment)
# [1] "nonchilled" "nnchilled" "chilled" "chiled"
65 / 121

Jeu de données "endommagé"

ERREUR 4 - Solution

# 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"
66 / 121

Jeu de données "endommagé"

ERREUR 4 - Solution

Après avoir réparé les facteurs, il faut enlever les niveaux de facteur non utilisés

Sinon :

boxplot(uptake ~ Treatment, data = CO2)

67 / 121

Jeu de données "endommagé"

ERREUR 4 - Solution

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 ...
boxplot(uptake ~ Treatment, data = CO2)

68 / 121

Bienvenue dans le monde de tidyverse !

69 / 121

Qu'est ce que Tidyverse?

Tidyverse 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")

Par exemple :

  • tidyr: réorganiser les tables de données
  • dplyr: manipuler les données
  • maggritr: lier plusieurs opérations
  • ggplot2: faire des graphiques
  • readr: lire les données (plus rapide !)
  • lubridate: manipuler des données de dates et de temps
  • et plus !
70 / 121

Manipulation de données avec

tidyr, dplyr, magrittr

71 / 121

tidyr pour réorganiser ses données

library(tidyr)

72 / 121

Format de données

Format large (wide)

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

Format long

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.

73 / 121

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() "rassembler" les données (large -> long)

pivot_wider() "disperser" les données (long -> large)

scale:90%

74 / 121

Installation du paquet tidyr

install.packages("tidyr")
library(tidyr)
75 / 121

Rassembler les colonnes en lignes

pivot_longer(data, cols, names_to, values_to, ...)

  • 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)
76 / 121

Rassembler avec pivot_longer()

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
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
77 / 121

Disperser avec les lignes en colonnes

pivot_wider(data, names_from, values_from, ...)

  • 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)
78 / 121

Disperser avec pivot_wider()

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
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
79 / 121

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.

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
80 / 121

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:

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

81 / 121

separate() des colonnes

separate(data, col, into, sep)

  • data Un data frame (e.g. long)
  • col Nom de la colonne que nous voulons séparer
  • into Nom des nouvelles colonnes crées par la séparation
  • sep Caractère qui indique où séparer le contenu
82 / 121

Utiliser separate()

Créons un jeu de données fictif sur les poissons et le zooplancton :

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
83 / 121

Utiliser separate()

On peut commencer par convertir ce jeu de données vers le format long.

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
84 / 121

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

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

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).

85 / 121

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

86 / 121

Défi #1

Réorganisez le jeu de données airquality en format long (en rassemblant toutes les colonnes sauf "Month" et "Day").

?airquality
data(airquality)
87 / 121

Solution #1

Réorganisez le jeu de données airquality en format long (en rassemblant toutes les colonnes sauf "Month" et "Day").

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
88 / 121

Défi #2

Convertissez-le en format large pour retrouver le format original de airquality

89 / 121

Solution #2

Convertissez-le en format large pour retrouver le format original de airquality

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
90 / 121

Manipulation avec dplyr

91 / 121

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()

92 / 121

Introduction à dplyr

Commençons par installer et charger le paquet dplyr

library(dplyr)
93 / 121

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)
94 / 121

select() - Sélection de colonnes

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 :

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."
95 / 121

select() - Sélection de colonnes

96 / 121

select() - Sélection de colonnes

Par exemple, si on analyse la variation de la variable Ozone avec le temps.

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
97 / 121

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, ...)


98 / 121

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

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
99 / 121

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), ...)

100 / 121

Ordonner des lignes avec arrange()

Example :

1) Commençons par créer une version désordonnée de airquality:

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
101 / 121

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

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

Essayez arrange(air_mess, Day, Month) et voyez la différence.

102 / 121

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, ...)

103 / 121

mutate() - Créer de nouvelles colonnes

Par exemple, on veut transformer la variable température Temp de degrés Fahrenheit vers degrés Celsius

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
104 / 121

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.

105 / 121

magrittr

Commençons par installer et charger le paquet :

library(magrittr)
106 / 121

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

juin_C <- mutate(filter(airquality, Month == 6),
Temp_C = (Temp-32)*(5/9))

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.

107 / 121

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 %>% :

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
108 / 121

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() regrouper le jeu de données 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())

109 / 121

dplyr - Séparer-Appliquer-Combiner

La fonction group_by est la base de la stratégie Séparer-Appliquer-Combiner

110 / 121

dplyr - Séparer-Appliquer-Combiner

111 / 121

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:

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
112 / 121

Défi - dplyr et magrittr

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" %>%.

## ?ChickWeight
data(ChickWeight)
113 / 121

Solution

  1. Utilisez group_by() pour grouper le jeu de données ChickWeight
  2. Utilisez summarise() pour calculer la gain de poids par groupe
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
114 / 121

NINJA Défi - dplyr et magrittr


  • 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" %>%.


Indice les fonctions first() et last() pourraient s'avérer utiles

115 / 121

Solution ninja

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.
116 / 121

Défi R base

Maintenant essayez de refaire le même exercice mais **seulement avec les fonctions de bases de R Prenez note qu'il existe plusieurs solutions.

Indice: Les fonction ?aggregate() ou ?by() pourraient s'avérer utiles.

117 / 121

Défi R base - Solution

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")
# 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
118 / 121

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.

119 / 121

Ressources supplémentaires

Pour en savoir plus sur dplyr

dplyr et tidyr anti-sèche

120 / 121

Merci pour votre participation! :)

121 / 121

À propos de cet atelier

badge badge badge badge

2 / 121
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow