Cette formation a pour but de rendre accessible à tous la programmation en R. Pour cela, nous introduirons la notion de programmation dans un contexte général, puis nous nous pencherons sur le langage R en partant d’une vue globale pour entrer petit à petit dans les manipulations techniques.
Comme nous l’informe Wikipédia, la programmation - aussi appelée codage ou développement, désigne l’ensemble des activités qui permettent l’écriture de programmes informatiques. Cette écriture de programmes se fait dans un langage de programmation, les 10 principaux langages sont les suivants : HTML/CSS, JavaScript, PHP, Ruby, Java, Swift, C#, C ou C++, Python, Julia et Scala. R est aussi un langage de programmation qui est, lui, davantage axé sur l’analyse statistique.
La troisième révolution industrielle, connue sous le nom de “révolution informatique” s’accompagne d’une création de 2.5 trillions d’octets de données chaque jour. C’est dans ce contexte d’abondance de données qu’est née la science de données, visant à obtenir des informations et des connaissances à partir de données qui génèrent de la valeur. Le schéma ci-dessous peut aider à comprendre comment exploiter la valeur des données :
Comme dit précédemment R est un langage de programmation en libre accès créé en 1993 par Ross Ihaka et Robert Gentleman, destiné aux statistiques et à la science de données.
Gratuit, facile d’accès, puissant, reproductible, design, le langage R est à la fois pertinent pour analyser les données, les visualiser et générer des rapports qui permettent - comme celui-ci, de mélanger du code, du texte et des graphiques.
Pour coder en R on utilise généralement l’interface R studio qui permet d’interagir avec le langage R de manière aisée. Quoi qu’il en soit, l’image suivante montre que la programmation est un apprentissage infini :
Pour installer l’interface RStudio il faut dans un premier temps installer R et dans un second temps télécharger l’application RStudio. Les liens de téléchargements sont disponibles sur le site rstudio.com.
Une fois l’installation terminée, il est important de configurer RStudio pour faciliter le travail sur l’interface et les partages de documents. Les paramètres généraux se trouvent dans le menu : Tools > Global Options
Vous pouvez configurer le ‘General’ et le ‘Code’ de la manière suivante :
Il est aussi important de configurer la sauvegarde des scripts ; il faut spécifier un codage “UTF-8” pour que les caractères spéciaux de chaque script enregistré soient traités correctement, et ainsi faciliter le partage de codes. Cette option est disponible dans la fenêtre des Global Options > Code > Saving > Default text encoding > Change… > UTF-8. Enfin, dans cette même fenêtre des options générales de RStudio - dans l’option “Appearance”, vous pouvez personnaliser l’apparence de votre interface en modifiant la police, la taille du texte, le thème etc. Le zoom qui peut se faire via cette option peut aussi se faire avec un raccourci clavier : Ctrl/Shift/+ pour zoomer et Ctrl/</- pour dézoomer.
Ne pas oublier d’appliquer ces changements (‘Apply’) avant de fermer la fenêtre des options (‘Ok’).
Une fenêtre R à son ouverture est décomposée en 3 parties, 4 en diminuant la taille de la partie inférieure en cliquant sur le bouton (ou via le menu : View > Panes > Show all panes). La programmation à proprement parler se fait dans la partie supérieure gauche, c’est là où on écrit les scripts que l’on pourra ensuite sauvegarder.
NB : il est aussi possible de coder directement dans la console (partie inférieure gauche), la commande sera exécutée mais ne sera pas sauvegardée ; ça peut donc être intéressant pour exécuter une commande de manière instantanée (un calcul par exemple).
La partie inférieure droite est décomposée en 5 onglets :
Un avantage incontournable de R est la communauté qui existe autour pour trouver des ressources, de l’aide, de l’inspiration etc. On trouve notamment R-bloggers avec des nouveautés et des tutoriels écrits par des utilisateurs du langage, RStudio Community pour trouver/donner de l’aide (comme un #TeamOpenData de RStudio), Stack Overflow où l’on trouve la majorité des réponses aux questions de programmation - la plateforme n’est cependant pas propre à R.
Il est aussi possible de relier RStudio à Git, ce qui permet de déposer du code, des bases de données et des objets créés (graphiques, cartes, documents html..) sur github. Les fichiers sont ainsi centralisés et sauvegardés sur un repository qui permet de collaborer facilement sur un projet. Vous trouverez un tutoriel de configuration à cette adresse.
coder = programmer
ligne de commande = ligne de code
run = exécuter une commande (bouton ‘Run’)
package = ensemble de fonctions
library = endroit où sont gardés les packages
working directory = répertoire de travail
Les principaux documents que l’on peut créer à partir de l’interface RStudio sont les suivants :
Pour créer un nouveau document il faut aller dans le menu : File > New File > choisir celui que vous voulez créer, ou sur le juste en dessous du ‘File’ dans la barre de menu.
Ces documents peuvent être créés/ouverts seuls ou dans un projet : . Un Rproject est utile dès lors que l’on travaille sur une analyse avec de nombreux fichiers (données, scripts, images…) et en collaboration avec d’autres personnes. Il est effectivement possible d’organiser son espace de travail à partir de l’objet ‘.Rproj’ :
/
et non des
\
) :data <- read_csv("C:/Users/name/desktop/mon_projet/data/base.csv")
La limite de cette méthode apparaît quand on veut partager le code à quelqu’un d’autre qui n’aura pas le même chemin d’accès (ne serait-ce que pour le nom d’utilisateur). En travaillant dans un projet R, les chemins d’accès aux documents seront relatifs puisqu’ils débutent à l’endroit où l’on travaille (working directory), c’est-à-dire à l’emplacement du .Rproj. La commande pour importer les données avec le chemin relatif serait la suivante :
data <- read_csv("./data/base.csv")
Le point “.” correspond au répertoire de travail c’est-à-dire à l’emplacement du RProject ici. Le dossier avec le projet R peut être déplacé et partagé, l’import continuera de fonctionner grâce au chemin relatif.
Pour créer un nouveau projet il faut aller dans le menu : File > New Project > New Directory > New Project > entrer un nom de projet, éventuellement changer l’espace de travail > Create Project, ou à partir du juste en dessous du ‘Edit’ dans la barre de menu.
Comme dit précédemment, il est possible de déposer des fichiers (scripts, données, images, pages HTML) sur la plateforme github et ainsi profiter de ses fonctionnalités (historique des dépôts, taguer une version, éditer en local ou en ligne, reporter un problème etc.). Cela est rendu possible par l’utilisation de projets R.
Bonne pratique
Un bon réflexe à prendre dès le début de votre carrière de
programmeur est de ne laisser aucun espace blanc dans
les noms des fichiers/dossiers, de manière à ce qu’ils puissent être lus
à la fois par des personnes mais aussi par des machines. Les bons
séparateurs des mots sont alors -
ou _
. Il est
aussi recommandé de ne pas mettre d’accent, pour
prévenir d’éventuels problèmes d’encodage.
Exemple de mauvais nom :
Extraction des données de data.gouv.R
Exemple de bon nom :
Extraction_donnees_data-gouv.R
Maintenant que la notion de programmation est plus claire et que vous connaissez les rouages du langage R, nous allons entrer dans le vif du sujet en apprenant à manier les données ; que ce soit la mise en forme, l’analyse ou la visualisation. Cette partie reprendra étape par étape le schéma d’exploitation des données que nous avons vu en première partie :
Avant de nous pencher sur l’import de données, voyons les deux manières de coder en R : le R-base et le tidyverse. La programmation dans le langage R a été révolutionnée ces dernières années par le statisticien Hadley Wickham et son équipe, qui ont développé le tidyverse. Contraction de tidy et universe, le tidyverse est une collection de packages R qui ont tous la même structure, simplifiant ainsi leur utilisation pour la data science.
Le tidyverse fonctionne grâce au pipe (%>%)
contenu dans le package magrittr
, qui permet d’appliquer un
certain nombre de fonctions à une base de données. Le code est alors
plus lisible grâce à une structuration des séquences d’opérations de
gauche à droite (et non de l’extérieur à l’intérieur
comme en R-base), qui permet d’ajouter des étapes
n’importe où dans les séquences d’opérations.
Un exemple de code en R-base et en tidyverse :
h(g(f(x)))
x %>% f %>% g %>% h
Nous apprendrons à coder principalement en tidyverse dont l’approche est beaucoup plus simple pour débuter la programmation.
Pour exécuter du code il faut placer son curseur sur la ligne de commande, puis cliquer sur le bouton en haut de la fenêtre, ou appuyer sur les touches Ctrl/Enter. Pour exécuter plusieurs lignes de code simultanément il suffit de les sélectionner avant de les runer. Vous pouvez notamment vous entraîner en runant de simples opérations arithmétiques :
13+4
#> [1] 17
5*2
#> [1] 10
13+4-5*2
#> [1] 7
Il est possible d’assigner une valeur à un objet
(dataframe, liste, vecteur, fonction…) avec <-
ou
=
(<-
s’utilise davantage et peut se
faire avec le raccourci clavier Alt/6), de manière à les
sauvegarder dans l’environnement de travail (partie en
haut à droite de la fenêtre RStudio). Vous pouvez par exemple
runer les commandes suivantes :
# Opérations
x <- 13+4
y <- 5*2
# Calcul du résultat
resultat <- x-y
resultat
#> [1] 7
De cette manière, le code sous R se lit de droite à gauche ;
Bonne pratique
Tout texte peut être intégré dans un script R après un “#” ; il ne sera pas considéré comme du code mais comme un commentaire donc ne sera pas exécuté. Un bon réflexe est de mettre le plus d’explications du code grâce aux “#”, pour qu’il soit lisible et compréhensible par toute personne qui travaillerait sur le script.
Comme dit précédemment, un package contient un certain
nombre de fonctions qui permettent de faire toutes
sortes de manipulations sur des bases de données ou autres. Le
repository officiel où sont stockés tous les packages R est
appelé CRAN ; “the Comprehensive R Archive Network”.
Pour installer un package depuis le CRAN il faut utiliser la fonction
install.packages("nom_package")
. Mais il existe d’autres
dépôts des packages créés, tel que Git (GitHub, GitLab, Bitbucket…) ;
pour installer un package stocké sur github par exemple il faut
utiliser la fonction
install_github("user_name/package_name")
, elle-même
contenue dans le package devtools.
Pour utiliser un package, après l’avoir installé, il faut l’appeler
via la fonction library(nom_package)
. Le code ci-dessous
permet d’installer les packages fondamentaux, il faut le copier, le
coller dans un script R basique (File > New File > R
Script) puis l’exécuter.
packages <- c("tidyverse", "readxl", "remotes", "devtools", "rmarkdown", "rio")
install.packages(packages)
Plusieurs packages sont attachés au “tidyverse” :
Il est possible d’importer des données dans l’environnement RStudio de deux manières : par un fichier exporté présent sur notre machine, ou directement via un lien qui pointe vers le téléchargement de ce fichier en ligne. La fonction utilisée pour importer un même jeu de données via son fichier ou via son lien, sera la même ; l’une sera composée du chemin vers le fichier sur la machine, l’autre du lien internet pointant vers l’export. Voici quelques exemples de plates-formes où il est possible d’en importer les données sans besoin préalable d’exporter le fichier :
Bonne pratique
Un autre bon réflexe est de privilégier tant que possible l’import via un lien, puisque ça n’implique aucune manipulation extérieure au script, donc une plus grande reproductibilité pour partager ou automatiser le code.
Il existe un certain nombre de formats de jeux de données, nous allons lister les plus courants en précisant la commande qui permet de les lire sous R et importer les données correctement.
library(readxl)
data <- read_excel(path = "chemin_acces/vers_le/fichier.xlsx", sheet = "feuille_n_1") # préciser le nom de la feuille à importer s'il y en a plusieurs
library(readr)
data <- read_csv("fichier.csv")
library(readr)
data <- read_delim("fichier.csv", delim = ";")
library(readr)
data <- read_delim("fichier.txt") # le délimiteur est reconnu automatiquement par R, c'est "\t"
# ou
data <- read_table("fichier.txt")
Il existe encore bien d’autres formats de fichiers tels que XML, JSON, SAS… Si besoin, vous trouverez toute l’aide nécessaire sur internet (notamment sur Stack Overflow vu en partie précédente).
Astuce
Lorsque vous avez un doute sur l’utilisation d’une fonction et que vous voulez savoir quels arguments elle attend et comment les spécifier, vous pouvez placer le curseur de la souris sur le nom de la fonction écrite dans le script puis appuyer sur les touches Fn/F1 ; la page d’aide de la fonction s’ouvrira dans la partie inférieure droite (Help) de la fenêtre RStudio.
D’une manière générale vous trouverez tous les raccourcis clavier dans le menu : Tools > Keyboard Shortcuts Help. Les plus utiles sont les suivants :
<-
: Alt/6 ;%>%
: Ctrl/Maj/m;Si vous avez un doute pour importer vos données, vous pouvez le faire en presse-bouton via le menu : File > Import Dataset > From
Il est possible de “jouer” avec les paramètres si ceux par défaut ne sont pas bons ; par exemple changer le séparateur de valeurs (Delimiter), l’encoding pour reconnaître les caractères spéciaux (Locale : Configure…), le nom de la base de données (Name), le nombre de lignes à ignorer en cas d’en-tête sur le fichier (Skip). Avant de finaliser l’import des données par le menu, il est important de copier le code qui apparaît en bas à droite de la fenêtre (Code Preview) puis le coller dans le script, pour ne pas refaire cette manipulation à chaque ouverture du script, et pour le rendre reproductible.
Entre une liste de notes d’élèves et une liste de noms de villes, on voit bien que la structure de données est différente. Listons ici les différents types de données qui existent, avant de voir comment les nettoyer :
Famille de données | Structure | Nom retourné sous R | Exemple |
---|---|---|---|
quantitatif | entier | int = integer | 3 |
décimal inexact | dbl = double | 3.4 | |
décimal exact | num = numeric | 3.400001 | |
qualitatif | chaîne de caractères | chr = character | Ville de Paris |
facteur à n niveaux | Factor | petit / moyen / grand | |
facteur à 2 niveaux dit “booléen” | bool = boolean | 0 / 1, True / False | |
autre | date | POSIX | 13-12-1998 |
Bonne pratique
Bien que numériques, les identifiants tels que numéros de SIREN, numéros de marchés, etc. doivent être considérés comme une chaîne de caractères et non une valeur numérique, pour éviter de perdre le premier chiffre si c’est un 0 par exemple.
Une fois importée, il est possible de regarder la structure
des données qui composent la base grâce à la fonction str()
:
# On importe des données ODS
data(iris)
# On regarde le type des variables qui composent la base
str(iris)
#> 'data.frame': 150 obs. of 5 variables:
#> $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#> $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
#> $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#> $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
#> $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
Nous réaliserons toutes sortes de manipulations sur une base de données déjà chargée dans l’environnement RStudio, c’est la base iris. Cette base recense des mesures de 4 attributs de 150 fleurs appartenant à 3 familles différentes. Plus d’informations sur les données sur ce lien.
Il arrive que la structure d’une variable ne soit pas la bonne, il
faut alors la changer pour avoir les données au bon format. Cela est
possible grâce à la fonction as.type_souhaite()
:
# Pour passer en chaîne de caractères la variable "Species"
iris$Species <- as.character(iris$Species)
# Pour passer en nombres décimaux arrondis les 4 autres variables (sans le faire une par une)
iris[,c(1:4)] <- lapply(iris[,c(1:4)], as.double)
Astuce
Pour accéder à une variable dans une base de données, il est possible d’utiliser le “$” qui correspond à du code en R-base. Il fonctionne de la manière suivante ; base_de_donnees$variable.
La fonction lapply() permet d’appliquer une fonction à plusieurs variables simultanément et permet ainsi de réduire le nombre de lignes de code dans le script.
Voilà quelques fonctions pour observer les données lorsqu’elles viennent d’être importées :
# 5 premières lignes
head(iris, 5)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3.0 1.4 0.2 setosa
#> 3 4.7 3.2 1.3 0.2 setosa
#> 4 4.6 3.1 1.5 0.2 setosa
#> 5 5.0 3.6 1.4 0.2 setosa
# 5 dernières lignes
tail(iris, 5)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 146 6.7 3.0 5.2 2.3 virginica
#> 147 6.3 2.5 5.0 1.9 virginica
#> 148 6.5 3.0 5.2 2.0 virginica
#> 149 6.2 3.4 5.4 2.3 virginica
#> 150 5.9 3.0 5.1 1.8 virginica
# Nombre de colonnes
ncol(iris)
#> [1] 5
length(iris)
#> [1] 5
# Nombre de lignes
nrow(iris)
#> [1] 150
# Nombre de lignes ET nombre de colonnes
dim(iris)
#> [1] 150 5
# Nom des colonnes
names(iris)
#> [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
# Résumé des valeurs d'une variable
summary(iris$Petal.Length)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 1.000 1.600 4.350 3.758 5.100 6.900
# Occurrences des valeurs d'une variable (approprié aux variables catégorielles)
table(iris$Species)
#>
#> setosa versicolor virginica
#> 50 50 50
# Nombre de valeurs uniques d'une variable (approprié aux variables catégorielles)
dplyr::n_distinct(iris$Species)
#> [1] 3
# Nom, structure et premières valeurs des colonnes
dplyr::glimpse(iris)
#> Rows: 150
#> Columns: 5
#> $ Sepal.Length <dbl> 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.…
#> $ Sepal.Width <dbl> 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.…
#> $ Petal.Length <dbl> 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.…
#> $ Petal.Width <dbl> 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.…
#> $ Species <chr> "setosa", "setosa", "setosa", "setosa", "setosa", "setosa…
Il arrive souvent que certaines valeurs manquent à une base de
données, elles peuvent alors prendre plusieurs écritures : NA, NaN, N/A,
NC, NULL… La plus connue étant “NA” qui signifie Not Available.
La fonction is.na()
peut être appliquée pour connaître le
nombre de valeurs manquantes dans une base de données, et
na.omit()
pour supprimer toutes les lignes qui contiennent
au moins 1 valeur manquante.
# Compter le nombre de NA dans une colonne
data %>% count(is.na(nom_colonne))
# Retirer toutes les lignes avec au moins 1 NA
new_data <- na.omit(data)
On parle de “tidy data” à partir du moment où les données sont propres, c’est-à-dire qu’elles respectent le schéma ci-dessous :
Chaque ligne est une observation et chaque colonne est une variable correspondant à l’observation en question. Selon le format des données, les observations peuvent correspondre à :
Dans un premier temps nous allons voir les différentes fonctions qui composent le dplyr et permettent de transformer les données, il s’agit des fonctions suivantes :
rename()
: pour changer le nom des colonnes
(renommer)select()
: pour sélectionner certaines colonnes et/ou
changer leur ordrefilter()
: pour sélectionner certaines lignes à partir
d’une conditionmutate()
: pour créer de nouvelles variablesarrange()
: pour réordonner les lignessummarise()
: pour résumer plusieurs valeurs en 1
valeur (moyenne, médiane, mode…)group_by()
: pour grouper les observations avant
d’appliquer une fonctionrename()
Cette fonction permet de renommer une ou plusieurs colonnes d’un
dataframe, elle fonctionne de la manière suivante :
data <- data %>% rename(nouveau_nom = ancien_nom)
.
Ci-dessous un exemple :
# On appelle la librairie tidyverse qui contient toutes ces fonctions et le pipe
library(tidyverse)
# On renomme 2 colonnnes
iris <- iris %>% rename(espece = Species,
longueur_petale = Petal.Length)
# Noms de colonnes en majuscules
names(iris) <- names(iris) %>% toupper
# Noms de colonnes en minuscules
names(iris) <- names(iris) %>% tolower
select()
Cette fonction permet de sélectionner certaines colonnes, cela est possible en les identifiant par leur nom ou leur position dans le dataframe (numéro de colonne). Quelques exemples :
# Sous df (dataframe) avec 2 colonnes
df1 <- iris %>% select(espece, sepal.width)
# ou
df1_bis <- iris %>% select(5, 2)
# Sous df sans 1 colonne
df2 <- iris %>% select(-longueur_petale)
# ou
df2_bis <- iris %>% select(-3)
# Sous df sans 2 colonnes
df3 <- iris %>% select(-c(longueur_petale, petal.width)) # c() permet de mettre dans 1 objet plusieurs arguments séparés par des virgules
# ou
df3_bis <- iris %>% select(-c(3,4))
# On change l'ordre des colonnes
iris <- iris %>% select(5,2:4,1)
Astuce
Lorsqu’un nom de colonne contient un espace (par exemple : taille
individu) il faut l’entourer de backticks (`) pour
qu’il soit reconnu comme le nom d’une seule colonne par R. Sans cette
astuce, la commande ne pourra pas s’exécuter, d’où l’importance de
nommer les bases de données et leurs variables par des noms séparés par
le caractère _
.
Exemple de mauvaise commande : data$premier nom <- as.numeric(data$premier nom)
Exemple de bonne commande : data$`premier nom` <- as.numeric(data$`premier nom`)
filter()
Cette fonction sert à sélectionner des lignes dans une base de données (dataframe ; df). Les lignes qui répondent à un certain critère ou condition logique sont sélectionnées. Les filtres peuvent être appliqués tant aux variables quantitatives que qualitatives. Par exemple :
# Fleurs de l'espèce "versicolor"
df4 <- iris %>% filter(espece == "versicolor")
dim(df4)
#> [1] 50 5
# Fleurs dont les pétales sont supérieurs ou égaux à 5 cm
df5 <- iris %>% filter(longueur_petale >= 5)
dim(df5)
#> [1] 46 5
# Fleurs de l'espèce versicolor ET dont les pétales sont supérieurs ou égaux à 5 cm
df6 <- iris %>% filter(espece == "versicolor" & longueur_petale >= 5)
dim(df6)
#> [1] 2 5
# Fleurs dont les pétales sont exactement larges de 2 OU de 2.5 cm
df7 <- iris %>% filter(petal.width == 2 | petal.width == 2.5)
dim(df7)
#> [1] 9 5
Avec le pipe () on
part de la base de données entière puis on applique nos filtres. On
obtient ici quatre sous-dataframes, et grâce à la fonction
dim()
on voit que l’on a :
Le tableau ci-dessous résume les filtres que l’on peut appliquer sur une ou plusieurs variable(s) d’une base de données. Pour filtrer des variables qualitatives il faut mettre la condition entre guillemets pour que le programme reconnaisse qu’il s’agit d’un texte.
Equation | Traduction pour R | Exemple |
---|---|---|
égal | == | Species == “versicolor” |
différent | != | Species != “setosa” |
supérieur | > | Petal.Length > 5 |
supérieur ou égal | >= | Petal.Length >= 5 |
inférieur | < | Petal.Length < 5 |
inférieur ou égal | <= | Petal.Length <= 5 |
mutate()
Cette fonction permet de créer de nouvelles variables à partir des variables existantes, elle est très utile pour l’analyse de données. Elle fonctionne de la manière suivante :
data <- data %>% mutate(nouvelle_colonne = ancienne_colonne*100)
La “mutation” peut être arithmétique comme textuelle.
# On créé 1 colonne et on modifie 1 autre
iris <- iris %>% mutate(pourcentage_max_petale_width = petal.width / max(petal.width) *100,
espece = paste("L'espèce est", espece, sep = ": "))
# On affiche les 5 premières lignes des variables crées
head(iris[,c(1,6)], 5)
#> espece pourcentage_max_petale_width
#> 1 L'espèce est: setosa 8
#> 2 L'espèce est: setosa 8
#> 3 L'espèce est: setosa 8
#> 4 L'espèce est: setosa 8
#> 5 L'espèce est: setosa 8
La commande ci-dessus a par exemple permis de créer une variable qui informe à combien de points de pourcentage la largeur du pétale se situe par rapport à la largeur maximale.
En deuxième argument de la fonction mutate()
on modifie
la variable espece (on écrase l’ancienne variable) en ajoutant
du texte grâce à la fonction paste()
. Cette dernière permet
de coller du texte, ici avant chaque espèce de fleur on
ajoute “L’espèce est:”, puis on colle le nom actuel de l’espèce
qui se trouve dans la base (sep correspondant
au séparateur entre le texte ajouté et l’ancienne valeur).
arrange()
Cette fonction sert à réordonner les observations selon un ordre alphabétique ou numérique croissant ou décroissant. Quelques exemples ci-dessous :
# On trie par longueur de sépale ascendante
iris <- iris %>% arrange(sepal.length)
# On trie par longueur de pétale descendante
iris <- iris %>% arrange(desc(longueur_petale))
# On trie par espèce puis par largeur de pétale ascendante
iris <- iris %>% arrange(espece, petal.width)
Bonne pratique
Ici nous avons attribué les changements sur la même base de données “iris”, ce qui a “écrasé” l’ancienne par la nouvelle dans laquelle les observations sont triées d’une certaine manière. Lorsque vous êtes sûrs de vos modifications, vous pouvez attribuer les modifications au même nom d’objet ce qui écrasera l’ancien, mais dès lors que vous voulez garder une trace de la base initiale il convient de créer un nouvel objet, c’est-à-dire avec un nouveau nom qui apparaîtra dans votre environnement de travail (partie supérieure droite de la fenêtre RStudio).
summarise()
Cette fonction permet de résumer plusieurs valeurs en une seule, ce qui est très utile pour avoir quelques statistiques sur les bases de données.
# Calcul de la longueur moyenne des pétales
iris %>% summarise(moyenne_PL = mean(longueur_petale))
#> moyenne_PL
#> 1 3.758
# Calcul de la largeur maximale des sépales
iris %>% summarise(max(sepal.width))
#> max(sepal.width)
#> 1 4.4
# Calcul des minimums des mesures des pétales
iris %>% summarise(min(petal.width),
min(longueur_petale))
#> min(petal.width) min(longueur_petale)
#> 1 0.1 1
On peut aussi calculer des statistiques sur toutes les
variables à la fois avec la fonction
summarise_all()
:
# Calcul des médianes de toutes les variables quantitatives
iris %>% select(-espece) %>% summarise_all(median)
#> sepal.width longueur_petale petal.width sepal.length
#> 1 3 4.35 1.3 5.8
#> pourcentage_max_petale_width
#> 1 52
# Calcul des écart-types et de la variance
iris %>% select(-espece) %>% summarise_all(list(sd, var)) #list() quand plusieurs mesures à la fois
#> sepal.width_fn1 longueur_petale_fn1 petal.width_fn1 sepal.length_fn1
#> 1 0.4358663 1.765298 0.7622377 0.8280661
#> pourcentage_max_petale_width_fn1 sepal.width_fn2 longueur_petale_fn2
#> 1 30.48951 0.1899794 3.116278
#> petal.width_fn2 sepal.length_fn2 pourcentage_max_petale_width_fn2
#> 1 0.5810063 0.6856935 929.61
On voit que la médiane n’a pas été calculée pour la variable
‘espece’ puisqu’elle n’est pas numérique, la valeur retournée
est donc NA (Not Available). Pour la deuxième commande
qui calcule l’écart-type et la variance, on exclut donc cette variable
qualitative grâce à la fonction select()
que nous avons vu
précédemment.
Le tableau ci-dessous résume les différentes statistiques que l’on peut calculer sur les données, avec la fonction équivalente en R:
Opération | Commande R | Exemple |
---|---|---|
moyenne | mean | mean(Petal.Length) |
médiane | med | med(Petal.Length) |
étendue | range | range(Petal.Length) |
minimum | min | min(Petal.Length) |
maximum | max | max(Petal.Length) |
écart-type | sd | sd(Petal.Length) |
variance | var | var(Petal.Length) |
skewness | skewness | skewness(Petal.Length) |
kurtosis | kurtosis | kurtosis(Petal.Length) |
quantiles | quantile | quantile(Petal.Length, probs = seq(0, 1, 1/10) |
Le dernier argument des séquences de probabilités pour les quantiles précise le type de quantiles que l’on souhaite calculer :
quantile(Petal.Length, probs = seq(0, 1, 1/4)
: pour
obtenir les quartilesquantile(Petal.Length, probs = seq(0, 1, 1/10)
: pour
obtenir les décilesquantile(Petal.Length, probs = seq(0, 1, 1/100)
: pour
obtenir les centiles etc.group_by()
Cette dernière fonction principale du tidyverse permet de grouper les
variables, elle est spécialement utile en analyse de données pour
calculer des statistiques par groupe (genre, pays, espèce…).
group_by()
prend le dataframe et le
convertit en une base groupée pour laquelle les opérations seront
effectuées non plus sur la base entière mais pour chacun des groupes
identifiés.
# Nombre d'observations par groupe
iris %>% group_by(espece) %>% summarise(n())
#> # A tibble: 3 × 2
#> espece `n()`
#> <chr> <int>
#> 1 L'espèce est: setosa 50
#> 2 L'espèce est: versicolor 50
#> 3 L'espèce est: virginica 50
# Calcul de la taille moyenne des pétales par espèce
iris %>% group_by(espece) %>% summarise(mean(longueur_petale))
#> # A tibble: 3 × 2
#> espece `mean(longueur_petale)`
#> <chr> <dbl>
#> 1 L'espèce est: setosa 1.46
#> 2 L'espèce est: versicolor 4.26
#> 3 L'espèce est: virginica 5.55
On voit par exemple que l’on a 50 fleurs par espèce dans notre base, et qu’en moyenne l’espèce virginica a les plus longs pétales : 5.55cm.
Nous savons à présent comment traiter les données grâce aux principales fonctions du dplyr, mais une manipulation importante reste à apprendre ; les combinaisons de données. Il y a 4 types de fonctions dans le dplyr qui permettent la combinaison de données :
Toutes ces fonctions ont la même structure : les deux premiers arguments sont des dataframes, et le résultat sera une nouvelle base du même type que le df stipulé comme premier argument.
Pour illustrer les fonctions de jointures et les filtres nous les appliquerons aux 2 bases de données suivantes, reprises de la cheatsheet Data Wrangling :
Il y a 4 types de jointures applicables dès lors qu’une variable (colonne) est commune aux 2 df : cela peut être utile par exemple pour ajouter des informations d’une base extérieure (bases nationales telles que Sirene, Prénoms, DECP…) à une base existante.
Il est nécessaire d’avoir une variable de jointure, dite
“clé” (identifiants, numéros de SIRET, noms de
pays…) qui permettra d’unir les 2 bases, elle se spécifie dans
l’argument ‘by=’. Ici, la clé est x1
qui est
présente dans a comme dans b.
left_join(a, b, by = "x1")
: ajoute les lignes
communes de b à a. Cette fonction est
la plus utilisée pour ajouter des informations
extérieures à une base de données existante.
right_join(a, b, by = "x1")
: ajoute les lignes
communes de a à b
inner_join(a, b, by = "x1")
: joint en ne gardant
que les lignes communes aux 2 df
full_join(a, b, by = "x1")
: joint les données en
gardant toutes les valeurs
Astuce
Lorsque la variable de jointure (la clé) n’a pas le même nom dans les 2 bases à joindre, il est possible de spécifier les noms à matcher. La commande est alors la suivante (“col_1” correspondant au nom de colonne dans le df1, et “Col_n1” dans le df2) :
new_df <- left_join(df1, df2, by = c("col_1" = "Col_n1"))
semi_join(a, b, by = "x1")
: toutes les lignes dans
a qui matchent celles dans b
anti_join(a, b, by = "x1")
: toutes les lignes dans
a qui ne matchent pas celles dans
b
Pour illustrer les fonctions d’opérations et de liaisons nous les appliquerons aux 2 bases de données suivantes :
intersect(y, z)
: lignes qui apparaissent dans
y ET dans z
union(y, z)
: lignes qui apparaissent dans
y ET/OU dans z
setdiff(y, z)
: lignes qui apparaissent dans
y MAIS PAS dans z
bind_rows(y, z)
: ajoute z à
y en tant que nouvelles
lignes
bind_cols(y, z)
: ajoute z à
y en tant que nouvelles
colonnes
Bonne pratique
Les fonctions bind_rows()
(ou
rbind
) et bind_cols()
(ou cbind
) font de simples liaisons entre
2 jeux de données, sans match préalable sur les valeurs communes. Elles
ne peuvent donc être appliquées qu’aux bases de données qui ont
exactement les mêmes spécifications :
bind_rows()
bind_cols()
La partie de visualisation qui vient après l’import,
le nettoyage et le traitement est très importante dans la science et
l’analyse de données. Le mot-clé, ou plutôt le package clé pour
faire des graphiques sous R est ggplot
.
Initialement développé par Hadley Wickham, ce package permet de
créer facilement des graphiques de qualité avec une immense variété de
paramètres modifiables selon les besoins, ce qui permet de créer des
graphiques adaptés à tous types de problèmes.
Quelque soit le graphique voulu, il y a toujours 3 éléments qui
composent la fonction ggplot()
:
data=
aes(x,y)
) pour indiquer les variables
X (abscisses=axe horizontal) et
Y (ordonnées=axe vertical), contrôler
la couleur, la taille ou la forme du dernier composantgeom_**()
Le tableau ci-dessous reprend les principaux types de géométrie
faisables à partir de la fonction ggplot
:
Géométrie | Commande R | Exemple |
---|---|---|
Nuage de points | geom_point | |
Ligne | geom_line | |
Boîte à moustaches | geom_boxplot | |
Violon | geom_violin | |
Densité | geom_density | |
Histogramme | geom_histogram | |
Barres | geom_bar |
Nous allons maintenant construire un graphique
pas-à-pas en introduisant tous les paramètres modifiables à
partir du package ggplot
.
La structure de la fonction ggplot
est
la suivante, avec les 3 principaux éléments décrits ci-dessus :
# Modèle d'une fonction ggplot
ggplot(data = <DATA>) +
<GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
Sur nos données de fleurs (iris) nous construisons un premier graphique en nuage de points où nous introduirons peu à peu différents paramètres.
# On recharge les données iris pour ne pas avoir les modifications des parties précédentes
data(iris)
# Graphique en nuage de points
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length))
Sur ce graphique le plus basique :
ggplot
geom_**
qui est ajoutée par un +
(ici
geom_point puisque nous voulons un nuage de points)x
et y
du mapping.Nous pouvons personnaliser les points en spécifiant certains paramètres tels que :
color
ou colour
: la
couleur des pointssize
: la taille des points (par
défaut à 1)alpha
: l’opacité des points (0
< alpha < 1, où 1 correspond à une opacité totale qui est la
valeur par défaut)shape
: la forme des pointsAstuce
Pour tous ces paramètres, un argument normal peut être spécifie (‘red’ pour la couleur, 2 pour la taille etc.), mais il est aussi possible de mettre le nom d’une autre variable de manière à intégrer une information supplémentaire au graphique. Ce peut être une variable catégorielle pour la couleur, une variable numérique pour la taille des points etc.
# Graphique en nuage de points personnalisé
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length),
color = "blue", size = 2, alpha = 0.7, shape = 2)
Il existe sur R deux manières de renseigner les couleurs : soit en spécifiant la couleur par son nom (exemple : “brown”), soit en la spécifiant par son code Hex (exemple : “#dd9933”). Il s’agit d’une chaîne de 6 caractères (chiffres et/ou lettres) qui correspond à une couleur que l’on peut créer soi-même. Sur le tableau ci-dessous on retrouve une palette de couleurs déjà créées pour lesquelles on a le code HEX.
Les formes des points peuvent aussi être spécifiées de deux manières : soit par un chiffre (exemple : 18) qui correspond à une forme déjà définie visible dans le tableau ci-dessous, soit par un caractère - un seul (exemple : “B”), qui sera utilisé comme forme de point.
Les couleurs | Les formes |
---|---|
pour plus d’informations | pour plus d’informations |
# Forme et couleur selon l'espèce de fleur
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species))
# Taille et opacité selon la largeur du pétale
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, alpha = Petal.Width, size = Petal.Width))
Sur les graphiques ci-dessus on a défini les paramètres visuels des
points selon d’autres variables du dataframe ‘iris’. Comme il s’agit de
variables, leur spécification se fait à l’intérieur de la
parenthèse aes()
qui pour rappel, correspond aux
propriétés esthétiques.
Par défaut le nom des variables sera mis comme
label aux axes des abscisse et des ordonnées, mais il est
possible de les modifier ou d’ajouter des titres au graphique grâce à la
fonction labs()
, qui peut être ajoutée aux paramètres
actuels par un +
.
# Titres du graphique
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
labs(title = "Relation entre les longueurs des sépales et des pétales",
subtitle = "Différenciée par espèce de fleur",
caption = "Données de la base Iris",
x = "Longueur du sépale",
y = "Longueur du pétale")
Pour n’avoir aucun titre sur le graphique il suffit de spécifier
x
et y = NULL
dans la fonction
labs()
:
# Aucun titre
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
labs(x = NULL,
y = NULL)
Il est possible de modifier l’apparence du graphique (taille, polices et couleur des titres, fond du graphique, quadrillages etc.) de deux manières :
theme()
qui peut s’ajouter à la suite des
paramètres existant du graphique par un +
theme_**()
La liste complète des thèmes disponibles se trouve au lien ggplot2.tidyverse.org, voilà quelques exemples de thèmes appliqués à notre graphique en construction :
# Thèmes
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme_minimal()
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme_classic()
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme_light()
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme_dark()
D’autres encore sont disponibles dans le package
ggthemes
, l’utilisation est la même que pour les thèmes de
ggplot2
, après avoir installé le package
(install.package(“ggthemes”)). La liste des thèmes disponibles
dans ce package se trouve ici.
Les éléments de légende peuvent être modifiés comme arguments de la
fonction theme()
que nous venons de voir, il est possible
de modifier la position, le titre, les textes, les couleurs de la
légende. Quelques exemples :
# Position
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme(legend.position = "top") #top, bottom, left or right
# Paramétrage du titre de la légende
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme(legend.title = element_text(color="blue", size=10,
face="bold"))
# Paramétrage du texte de la légende
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme(legend.text = element_text(colour="red", size=10,
face="italic"))
# Supprimer la légende
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
theme(legend.position = "none")
Astuce
Bien que l’apparence puisse être définie par la fonction
theme_**()
, il est possible de modifier les paramètres du
thème existant en ajoutant après celle-ci la fonction
theme()
- dans laquelle il est par exemple possible de
modifier les éléments de la légende, comme ci-dessus.
Lorsque l’on veut représenter graphiquement les données par groupe on peut le faire de différentes manières :
Dans le package ggplot
ce sont les fonctions
facet_grid()
et facet_wrap()
qui permettent de
créer des ‘facettes’ à un graphique, selon une variable catégorielle (un
groupe).
# Facettes sur une seule ligne avec facet_grid
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
facet_grid(cols = vars(Species))
# Facettes sur une seule colonne avec facet_grid
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
facet_grid(rows = vars(Species))
# Facettes en matrice avec facet_wrap
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
facet_wrap(vars(Species), ncol = 2, nrow = 2)
La fonction lims()
permet de spécifier soi-même les
limites du graphique, de la manière suivante :
c(min, max)
.
# Modification des limites
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
lims(x = c(1,10), y = c(2,7))
Avec le package ggplot
il est facile de combiner
plusieurs géométries sur un même graphique. Sur les visualisations qui
suivent, nous avons ajouté une ligne qui relie tous les
points grâce à la fonction geom_line()
, puis une
ligne qui représente la tendance générale (courbe
lissée) grâce à la fonction geom_smooth()
.
# Geom_point + geom_line
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
geom_line(mapping = aes(x = Sepal.Length, y = Petal.Length))
# Geom_point + geom_smooth
ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species)) +
geom_smooth(mapping = aes(x = Sepal.Length, y = Petal.Length)) #ou stat_smooth()
Le boxplot, aussi appelé la boîte à
moustaches, permet de visualiser une
distribution, de la même manière qu’un
histogramme, violin plot ou graphique en
densité le permettent. Sur le graphique de droite nous ajoutons la
moyenne de chaque longueur de sépale par espèce, grâce à la fonction
stat_summary()
. Celle-ci permet d’intégrer aux graphiques
des statistiques, sans besoin de les calculer avant le graphique.
L’argument fun
permet de préciser le type de statistique
souhaité ; ici fun = mean
pour représenter par un point la
moyenne de la variable ‘Sepal.Length’.
# Box plot
ggplot(data = iris) +
geom_boxplot(mapping = aes(x = Species, y = Sepal.Length))
# Box plot avec valeur moyenne pour chaque espèce
ggplot(data = iris) +
geom_boxplot(mapping = aes(x = Species, y = Sepal.Length)) +
stat_summary(mapping = aes(x = Species, y = Sepal.Length), fun = mean, color = 'red')
Les histogrammes permettent aussi d’observer la distribution d’une variable, ils montrent le nombre d’observations par valeur. Ici par exemple, 4 fleurs ont un sépale de moins de 4.5 cm et 1 fleur a un sépale de 4.5 cm. Sur le deuxième graphique on distingue par espèce, ce qui permet d’observer des sépales plus longs pour l’espèce ‘virginica’ et plus courts pour l’espèce ‘setosa’.
# Histogramme
ggplot(data = iris) +
geom_histogram(mapping = aes(x = Sepal.Length))
# Histogramme coloré par groupe
ggplot(data = iris) +
geom_histogram(mapping = aes(Sepal.Length, fill = Species), #fill contrôle la couleur de remplissage
color = 'black') #color contrôle la couleur des bordures
Les graphiques en barres permettent de représenter
un montant, une répartition par variable catégorielle (groupes). Ces
derniers peuvent être faits via la fonction geom_bar()
ou
la fonction geom_col()
, entre lesquelles il existe une
différence. Effectivement, geom_col()
est un cas spécifique
de geom_bar()
où la statistique spécifiée est
‘identity’, tel que geom_bar(stat = "identity")
.
Par défaut, on ne spécifie qu’une variable catégorielle (X) dans les
paramètres esthétiques de geom_bar()
puis celui-ci
visualise le nombre d’occurrences de chaque valeur de
X. En ajoutant stat = "identity"
, geom_bar()
attend une variable numérique (Y) comme argument, de laquelle il
plotera les valeurs. Le même résultat peut
être obtenu en spécifiant X et Y avec la fonction
geom_col()
. Cette distinction est visible ci-dessous, avec
un jeu de données créé pour l’illustrer :
diff_geom_bar_col <- data.frame(x = c("A", "B", "C", "C"),
y = c(2, 3, 1, 5))
# Bar plot
ggplot(data = diff_geom_bar_col) +
aes(x = x) +
geom_bar() +
labs(x = "geom_bar() avec X spécifié : nombre d'occurrences visualisé")
# Bar plot
ggplot(data = diff_geom_bar_col) +
aes(x = x, y = y) +
geom_bar(stat = "identity") +
labs(x = 'geom_bar(stat = "identity") avec X et Y spécifiés : valeurs de Y visualisées')
# Bar plot
ggplot(data = diff_geom_bar_col) +
aes(x = x, y = y) +
geom_col() +
labs(x = 'geom_col() avec X et Y spécifiés : valeurs de Y visualisées')
#> x y
#> 1 A 2
#> 2 B 3
#> 3 C 1
#> 4 C 5
Pour revenir aux données iris, nous visualisons ici la
longueur des pétales selon l’espèce. S’agissant des valeurs de Y et non
du nombre d’observations par espèce (50 pour chacune d’elle), nous
utilisons l’option stat = "identity"
dans la fonction
geom_bar()
(nous aurions également pu utiliser
geom_col()
). Le deuxième graphique visualise les mêmes
informations mais avec les barres à l’horizontal, ce qui est possible
grâce à la fonction coord_flip()
que l’on ajoute à la suite
du code existant.
# Bar plot
ggplot(data = iris) +
geom_bar(aes(x = Species, y = Sepal.Length),
stat = "identity")
# Bar plot horizontal
ggplot(data = iris) +
geom_bar(aes(x = Species, y = Sepal.Length),
stat = "identity")
coord_flip()
Il existe encore bien d’autres géométries dans le package
ggplot
qui permettent de représenter toutes sortes de
variables. Les liens suivants aident à utiliser la bonne visualisation
selon ce que l’on cherche à représenter et/ou selon le type de variables
:
https://clauswilke.com/dataviz/directory-of-visualizations.html
https://rkabacoff.github.io/datavis/
Lorsque l’on cherche à combiner plusieurs graphiques sur une même
page on peut utiliser la fonction grid.arrange()
contenue
dans le package gridExtra
(install.packages("gridExtra")
pour l’installer). Pour
l’utiliser il faut au préalable sauvegarder les
graphiques créés dans un objet, de manière à les appeler dans la
fonction grid.arrange()
. Dans un premier temps on combine 2
graphiques côte à côte sur une même ligne donc sur 2 “colonnes”
(nrow = 1
, et ncol = 2
) :
# Box plot avec valeur moyenne pour chaque espèce
g1 <- ggplot(data = iris) +
geom_boxplot(mapping = aes(x = Species, y = Sepal.Length)) +
stat_summary(mapping = aes(x = Species, y = Sepal.Length), fun = mean, color = 'red')
# Histogramme coloré par groupe
g2 <- ggplot(data = iris) +
geom_histogram(mapping = aes(Sepal.Length, fill = Species),
color = 'black')
# Combinaison des graphiques
library(gridExtra)
grid.arrange(g1, g2, ncol = 2, nrow = 1)
Puis on les combine sur une même colonne donc sur 2 lignes
(nrow = 2
, et ncol = 1
) :
# Box plot avec valeur moyenne pour chaque espèce
g1 <- ggplot(data = iris) +
geom_boxplot(mapping = aes(x = Species, y = Sepal.Length)) +
stat_summary(mapping = aes(x = Species, y = Sepal.Length), fun = mean, color = 'red')
# Histogramme coloré par groupe
g2 <- ggplot(data = iris) +
geom_histogram(mapping = aes(Sepal.Length, fill = Species),
color = 'black')
# Combinaison des graphiques
grid.arrange(g1, g2, ncol = 1, nrow = 2)
Tous les graphiques que nous venons de voir jusqu’ici étaient
statiques, mais il est possible de les rendre
dynamiques grâce à la fonction ggplotly()
contenue dans le package plotly
(install.packages("plotly")
pour l’installer). Il suffit de
sauvegarder le graphique créé dans un objet puis de passer cet objet
dans la fonction ggplotly()
:
# Histogramme coloré par groupe
g1 <- ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species))
# Graphique dynamique
library(plotly)
#ggplotly(g1)
g1
Il est maintenant possible de zoomer sur le graphique, de capturer
une image, de passer le curseur sur les différentes valeurs etc. On peut
voir que lorsque l’on passe le curseur sur les points, les valeurs des
variables entrées dans la fonction apparaissent ; on a ici
‘Sepal.Length’, ‘Species’ et ‘Petal.Length’.
Mais il est possible de customiser ce texte
pour le rendre plus lisible, ce qui se fait directement dans le
graphique ggplot
puis est appelé dans la fonction
ggplotly()
.
# Histogramme coloré par groupe
g1 <- ggplot(data = iris) +
geom_point(mapping = aes(x = Sepal.Length, y = Petal.Length, color = Species, shape = Species,
text = paste("Fleur au pétale de", Petal.Length, "cm, et sépale de",
Sepal.Length, "cm",
"\n", "Espèce", Species))) #"\n" permet d'aller à la ligne
# Graphique dynamique
ggplotly(g1, tooltip = c("text"))
Comme on le voit dans la commande, il faut utiliser la fonction
paste()
qui permet de coller du texte
(entre guillemets) et la valeur des variables
en séparant le tout par des virgules. Ce texte est à rentrer
dans les paramètres esthétiques (aes()
), puis à appeler
dans la fonction ggplotly()
par l’argument
tooltip = c("text")
.
Une fois les graphiques créés, il est possible de les
exporter via la fonction ggsave()
contenue
dans le package ggplot
. Le premier argument correspond au
nom tel que sera exporté le graphique, le second (plot
)
correspond à l’objet créé sous R que l’on veut exporter, puis en 3è et
4è arguments peuvent être spécifiées les largeurs et hauteurs souhaitées
pour le graphique. Il s’enregistrera dans le working directory
actuel.
ggsave("mon_graphique.png", plot = g1, width = 8, height = 6)
Nous avons vu dans cette partie quelques bases pour construire un graphique sous R, mais beaucoup d’autres choses encore peuvent être ajoutées, modifiées etc. Vous pouvez trouver des modèles de graphique déjà construits sous R avec leur code sur R Graph Gallery, il ne reste plus qu’à les modifier pour les appliquer à nos données.
Astuce
De la même manière qu’il est possible d’importer des données en
presse-boutons, il est aussi possible de construire des
graphiques en presse-boutons récupérer le code, et l’intégrer
au script existant. Cela est faisable avec la fonction
esquisser()
contenue dans le package esquisse
(install.packages("esquisse")
pour l’installer). Pour
l’utiliser il suffit d’exécuter la commande suivante qui va ouvrir une
fenêtre permettant de construire un graphique pas-à-pas :
esquisse::esquisser()
.
Enfin, la dernière partie du schéma de traitement des données correspond à la communication des résultats. Nous ne verrons que les rapports R Markdown (Rmd) dans cette partie, qui permettent de combiner du texte, du code, des graphiques, des images et des tableaux avec une mise en page propre et totalement personnalisable. Un document Rmd se crée via le menu : File > New File > R Markdown. Il est alors possible de préciser un nom d’auteur et un titre au rapport, ainsi que le type de document qui sera généré. 3 types existent : un document html (comme celui-ci), un document PDF ou encore un document Word. Selon l’usage, le type de document choisi sera différent.
Astuce
Bien qu’il faille choisir le type de document dès la création du document Rmd, il est possible ensuite de changer le document alors qu’il est en cours d’écriture, ce qui permet de switcher facilement d’un format à un autre.
Tandis que les documents PDF et Word vont être séparés en pages et seront statiques, les documents html vont eux permettre d’intégrer des tables ou des graphiques interactifs, des cartographies, des onglets et bien d’autres choses encore.
Après avoir créé un document R Markdown, vous pouvez générer le
rapport en cliquant sur le bouton knit
qui se trouve à
droite du bouton de sauvegarde en dessous du titre du document.
Voici un exemple très simple de code R Markdown qui permet de générer un document au format html.
---
title: "Mon premier document Rmd"
author: "Moi"
date: "Décembre 2021"
output: html_document
---
Cette partie permet d'introduire le contenu du rapport dans sa globalité.
```\{r}
head(iris, 5)
```
La partie juste au-dessus est un chunk de code R. Quand on compile le document (knit), le code sera exécuté et le résultat se montrera en dessous dans le document html final.
L’output de ce bout de code sera le suivant (sans le
caractère \
qui sert à échapper le chunk pour pas qu’il ne
run dans le corps du texte lui-même) :
Dans tout document R Markdown on retrouve 3 types de contenus :
---
, dans lequel on peut préciser le tire, l’auteur, la
date et le type de document cet en-tête est optionnel)```
, dans lesquels on peut insérer du code qui sera exécuté
et apparaîtra dans le document finalLes éléments basiques et généraux peuvent être introduits dans l’en-tête du document, voici un exemple de header plus complet que l’on décomposera par la suite pour voir comment fonctionne chaque partie :
---
title: "Titre du document"
author: "Auteur du document"
date: "`r Sys.Date()`"
output:
html_document:
theme: journal
highlight: textmate
toc: yes
toc_float: yes
toc_depth: 2
---
Le paramètre date: "`r Sys.Date()`"
donne la date du
jour grâce à la fonction Sys.Date()
qui est mise à
l’intérieur de l’argument `r `
. Celui-ci permet d’exécuter
du code R intégré dans le corps du texte, sans besoin de créer un
chunk R. Les paramètres passés après l’argument
output:
servent à spécifier le type de rapport qui sera
généré, il s’agit ici d’un document html (il faudrait spécifier
output: pdf_document
pour un document PDF, et
output: word_document
pour un Word).
Avec un autre niveau d’alinéa on peut ensuite paramétrer la
mise en page avec les arguments theme
et
highlight
, puis la table des matières avec
toc
, toc_float
et toc_depth
.
theme
: il existe 12 thèmes qui ne
nécessitent pas de packages supplémentaires et qui peuvent être utilisés
facilement en spécifiant leur nom comme dans l’exemple ci-dessus
(theme: journal
). D’un thème à l’autre les polices, les
tailles et les couleurs du texte peuvent changer : une liste des thèmes
est disponible
ici.
highlight
: en complément à
l’argument theme
qui spécifie la mise en page du
texte (titres + corps du texte), l’argument
highlight
permet de paramétrer la mise en page du code (des
chunks) qui apparaît dans le rapport. Une liste des différents
thèmes pour le code est disponible
ici.
toc
: cet argument permet
d’intégrer une table des matières (Table of contents : TOC)
dans le rapport, elle sera générée automatiquement à partir du moment où
la valeur “yes” lui est attribuée. La table des matières
reprendra les titres et sous-titres du document.
toc_float
: cette option permet de
faire “flotter” la table des matières, de manière à ce qu’elle reste
toujours visible à gauche, même lorsque le document défile (comme sur ce
document).
toc_depth
: cette option contrôle
la profondeur de la table des matières : ici par exemple seuls les
titres de niveaux 1 et 2 apparaîtront dans la table.
Comme dit précédemment, les chunks sont des bouts de code R
qui permettent de faire des analyses et d’afficher les résultats dans le
document final. Le code est reconnu comme du code et non du texte dès
lors qu’il est placé après ```{r}
et avant
```
. On peut par exemple appeler des
librairies, importer des données, les manipuler, les visualiser et les
modéliser. Globalement ; tout ce qui est faisable dans un script basique
R (fichier.R
) est faisable aussi dans un R Markdown, avec
en plus la possibilité d’ajouter des commentaires, des titres, des
images etc.
Un chunk R peut être créé de la manière suivante :
Les chunks peuvent avoir plusieurs options qui permettent une plus grande flexibilité dans la manière dont le code et les résultats seront affichés dans le document final. Les principales options sont les suivantes (issues du livre “R for Data Science”) :
eval = FALSE
empêche l’évaluation
du code, donc aucun résultat ne sera généré. Cette option peut être
utile pour afficher un exemple de code sans l’exécuter.
include = FALSE
exécute le code,
mais n’affiche ni le code ni les résultats dans le document final. Cette
option peut être utile pour le code de configuration qu’on ne veut pas
afficher dans le rapport final.
echo = FALSE
empêche le code, mais
pas les résultats d’apparaître dans le fichier. Utile pour la rédaction
de rapports destinés à des personnes qui ne souhaitent pas voir le code
R sous-jacent.
message = FALSE
ou
warning = FALSE
empêche l’apparition de
messages ou d’avertissements dans le rapport final.
résultats = 'hide'
masque la sortie
imprimée ; fig.show = 'hide'
masque les
tracés.
error = TRUE
entraîne la poursuite
du rendu même si le code renvoie une erreur. La valeur par défaut,
error = FALSE
, entraîne l’échec du knit s’il y a
une seule erreur dans le document.
Ces différentes options peuvent être mises à la suite du
r
dans les accolades du chunk, il est possible
d’en mettre plusieurs qui doivent alors être séparées par des virgules
(exemple : ```{r eval = TRUE, echo = FALSE}
). Le tableau
ci-dessous récapitule les options et leur effet sur le document final
:
Options | Run code | Montre code | Résultats | Graphiques | Messages | Warnings |
---|---|---|---|---|---|---|
eval = FALSE | ✓ | |||||
include = FALSE | ✓ | |||||
echo = FALSE | ✓ | ✓ | ✓ | ✓ | ✓ | |
message = FALSE | ✓ | ✓ | ✓ | ✓ | ✓ | |
warning = FALSE | ✓ | ✓ | ✓ | ✓ | ✓ | |
results = “hide” | ✓ | ✓ | ✓ | ✓ | ✓ | |
fig.show = “hide” | ✓ | ✓ | ✓ | ✓ | ✓ |
Astuce n°1
Il est possible de montrer ou de cacher tous les chunks par défaut en
spécifiant l’option dans le YAML header. Dans l’exemple qui suit, tous
les codes seront montrés par défaut (“hide
” pour cacher
tous les codes par défaut) :
---
title: "Titre du document"
author: "Auteur du document"
date: "`r Sys.Date()`"
output:
html_document:
theme: journal
toc: yes
code_folding: show
---
Astuce n°2
Au lieu d’écrire manuellement les options dans les chunks entre les accolades, il est possible d’utiliser le bouton qui se trouve en haut à droite du chunk.
Lorsque l’on veut définir des options de chunk qui soient valables
pour tous les chunks du document, il est possible de
les définir d’une manière générale (par défaut) au début du script R
Markdown. Cela est faisable grâce à la fonction
opts_chunk$set()
du package knitr
(install.packages("knitr")
pour l’installer). Voici un
exemple de chunk qui définit les options par défaut, il est à
placer au début du document, après le YAML header.
library(knitr)
opts_chunk$set(echo = TRUE, # affiche le code
message = FALSE, # cache les messages d'erreurs
warning = FALSE, # cache les messages d'avertissements
fig.align = "center", # centre les figures
out.width = "80%") # affiche les figures à 80% de leur taille
Dans un document R Markdown, tout ce qui n’est pas de l’en-tête ou du code - que nous venons de voir, correspond au corps du texte. Le texte s’écrit de la même manière qu’un fichier Word, mais la spécification de la mise en page va être différente : le texte en gras, les citations, les titres etc. Les captures d’écrans ci-dessous montrent comment faire les principales mises en forme de texte en markdown.
Texte brut | Rendu |
---|---|
Pour finir, voyons comment intégrer une image et un tableau à un document R Markdown.
Il y a plusieurs manières d’insérer une image dans un document Rmd, en voilà deux :
# Première façon
![](lien/vers/l_image.png){width=120%}
# Deuxième façon
```\{r out.width='80%'}
knitr::include_graphics(here::here("lien/vers/l_image.png"))
```
La taille de l’image est ajustable via les arguments
width
ou out.width
. La première commande pour
intégrer une image peut être placée telle quelle en corps de texte, dans
un tableau ou encore au sein d’une phrase, tandis que la deuxième façon
consiste à insérer un chunk R (sans le caractère \
qui
échappe le code) dans lequel on utilise la fonction
include_graphics()
qui permet d’afficher une image.
Il est possible d’intégrer, au texte d’un document Rmd, un tableau et le créer directement sur le script. Il existe cependant des outils qui permettent de réaliser cette tâche plus facilement. L’outil Tables Generator permet de construire un tableau comme sur un Word, puis de récupérer le code qu’il ne reste plus qu’à coller dans le script Rmd. Il est alors possible de choisir pour quel format le tableau doit être généré ; dans notre cas il convient de choisir Markdown, ou HTML si l’output spécifié dans l’en-tête du document (YAML header) est un html.
Au long de cette formation nous avons pu apprendre à manier les données sous toutes ses formes en R. Sur l’interface R Studio nous avons vu comment importer des données, les nettoyer, les transformer, les visualiser et communiquer sur l’analyse avec les documents Markdown de R. Il existe d’autres documents pour communiquer les résultats tels que slides, application Shiny, tableau de bord Flexdashboard etc. Si vous êtes curieux de connaître de tels outils, vous trouverez toutes les ressources nécessaires sur internet.
Il existe pour tous les livres créés pour R, un recensement complet que l’on trouve dans le livre : Big Book of R. Y sont rassemblés tous les tutoriels par thématique : Big Data, Data Science, Data Visualisation, Geospatial, Journalism…
Une référence incontournable pour approfondir la Data Science est le livre de Hadley Wickham & Garrett Grolemund ; R for Data Science (recensé en 10.2 dans Big Book of R).
En espérant que vous prendrez plaisir à programmer pour exploiter le potentiel des données, quittons-nous sur ce meme.
Combien de données sont créées chaque jour en 2021 ? - AFFDE
Essentials ggplot2 - Statistical tools for high-throughput data analysis (STHDA)
Programación y manejo de datos en la era del Big Data - Pedro J. Pérez
Document sous licence ouverte réalisé par Diane Thierry
diane@datactivist.coop