1 Présentation du langage R

Le langage de programmation R est un outil particulièrement puissant pour les calculs statistiques et l’analyse des données. Il est très utilisé dans le milieu de la recherche scientifique mais aussi dans le monde du Business. R peut être utilisé pour des tâches telles que la modélisation statistique, la visualisation des données, l’apprentissage automatique (Machine Learning), l’analyse des séries temporelles, les études économétriques, l’analyse quantitative, le traitement des données textuelles, etc. De plus, plusieurs packages ont été développé dans R afin de faciliter la création de data products (applications web interactives, rapports dynamiques, tableaux de bords, sites web et blogs, etc.) destinés à l’automatisation des tâches et à la communication des résultats d’un projet. R n’est donc pas un simple langage de programmation comme les autres mais plutôt un environnement intégré et complet pour la conception, la réalisation et la vulgarisation d’un projet concernant l’analyse des données.

L’environnement R possède plusieurs avantages dont voici une liste non-exhaustive :

  • R est un outil open-source pouvant s’exécuter dans plusieurs systèmes d’exploitation dont Linux, Windows et MacOS ;

  • R est très efficace pour le traitement et le stockage des données (y compris les données volumineuses type BigData) ;

  • R possède de nombreuses fontionnalités intrinsèques facilitant les études scientifiques ;

  • il est vrai et admis que R est extrêmement puissant pour accomplir des études statistiques. Par ailleurs cette puissance de R est étendue (par des packages) aux tâches plus complexes comme l’apprentissage automatique (Machine Learning), l’apprentissage profond (Deep Learning), le traitement du langage naturel (Natural Langage Processing ou NLP), etc.

  • R possède des librairies puissantes telles que R Markdown pour la création de documents (articles scientifiques, livres, rapports d’études, etc.) de très haute qualité et R Shiny pour la création d’applications web intercatives et à forte valeur ajoutée.

  • etc.

Les avantages cités ci-dessus et d’autres encore font de R une suite d’outils intégrés et cohérents pour le bonheur de ses utilisateurs.

2 Installation de l’environnement de travail

Pour travailler dans R, vous devez préalablement installer et configurer votre environnement de travail. Vous devez installer séparément R et RStudio dans votre ordinateur.

2.1 Téléchargement et installation de R

Vous pouvez télécharger R sur son site officiel.

  1. Choisir la version de R correspondante à votre système d’exploitation

Les étapes ci-dessous illustrent le téléchargement et l’installation de R pour PC Windows. L’installation de R dans Linux et MACOS se fait pratiquement suivant les mêmes étapes que celles de Windows.

  1. Cliquez sur install R for the first time

Même si vous aviez déjà installé R une fois dans votre ordinateur, vous pouvez quand même cliquez sur ce lien.

  1. Cliquez sur Download R 4.0.5 for Windows et choisissez un dossier dans votre PC pour enregistrer l’application.

Au moment où nous écrivons ce livre, la dernière version de R est la 4.0.5. Mais cela ne change rien quant au contenu de ce livre au cas où vous avez une autre version. De plus, le livre est régulièrement actualisé pour tenir compte d’éventuelles mises à jour des fonctionnalités de R.

Une fois que l’application a été téléchargé, ouvrez-le puis démarrer l’installation.

  1. Choisissez la langue d’installation et cliquez sur OK

  1. Cliquez sur Suivant

  1. Cliquez encore sur Suivant

  1. Cliquez encore sur Suivant

  1. Cliquez sur Non (accepter les valeurs par défaut) puis sur Suivant

  1. Cliquez encore sur Suivant

  1. Cliquez encore sur Suivant pour lancer l’installation

Une fois que la progression d’installation de l’application est complète :

  1. Cliquez sur Terminer pour fermer l’assistant d’installation

2.2 Téléchargement et installation de RStudio

RStudio est l’environnement de développement intégré (Integrated Development Environment ou IDE) le plus utilisé pour écrire du code R. Il est simple d’utilisation mais très puisant et efficace pour gérer différentes tâches. Vous pouvez télécharger RStudio en vous rendant sur son site officiel

  1. Une fois sur la page officielle de RStudio, cliquez sur DOWNLOAD

  1. Télécharger RStudio Desktop

Il existe plusieurs versions de RStudio. Toutes les tâches effectuées dans ce livre peuvent être effectuées avec RStudio Desktop qui est non seulement une version gratuite mais aussi la plus utilisée. Néanmoins les versions commerciales de RStudio (RStudio Desktop Pro et RStudio Server Pro) présentent des fonctionnalités additionnelles qui sont intéressantes pour des entreprises.

Le site web détecte automatiquement le système d’exploitation de votre ordinateur et vous propose de télécharger la version de RStudio correspondante.

3 Utilisation de RStudio

Une fois que vous avez installé R et RStudio dans votre ordinateur, vous pouvez maintenant commencer à écrire du code en utilisant RStudio comme IDE. L’interface de RStudio se présente comme suit :

Cette interface est composée de :

  1. Editeur du code : c’est à ce niveau que vous écrivez votre script (ensemble de lignes de commandes sous forme de fichier texte) R. Pour exécuter votre script, sélectionnez les lignes et cliquez sur Run

  2. Console : La console affiche les commandes qui ont été déjà exécutées. Soulignons que vous pouvez aussi écrire et exécuter une commande directement dans la console en appuyant sur la touche Entrée de votre clavier ;

  3. Espace de travail et Historique des variables : cette fenêtre affiche l’historique (noms et valeurs) de toutes les variables. L’historique s’actualise à chaque exécution de votre code ;

  4. Fichiers et Graphiques : cette fenêtre montre les fichiers se trouvant dans votre répertoire de travail et affiche aussi les différents graphiques.

4 Chapitre 1 : Prise en main de l’environnement R

Dans ce chapitre, la console est largement suffisante pour écrire et exécuter les différents codes. Néanmoins, vous pouvez aussi utiliser l’éditeur de code.

4.1 Programme “Hello World” et Opérations basiques

Il est courant de commencer l’apprentissage d’un nouveau langage informatique par l’écriture du célèbre programme Hello World. Dans R, cela se fait en une seule ligne de code.

print("Hello World")
## [1] "Hello World"

La fonction print() est une fonction intrinsèque de R utilisée pour afficher des résultats.

print('Hello World')
## [1] "Hello World"

Vous pouvez utiliser soit des doubles guillemets (” “) soit des guillemets simples (’ ’) pour afficher des chaînes de caractères. Mais dans certains cas, l’utilisation des doubles guillemets s’impose.

#print('Hello World ! Je m'appelle Diana')

Vous devez donc plutôt écrire :

print("Hello World ! Je m'appelle Josué")
## [1] "Hello World ! Je m'appelle Josué"

Il est possible d’aller à la ligne en utilisant la fonction cat() :

cat("Hello World !\nJe m'appelle Josué")
## Hello World !
## Je m'appelle Josué
cat("Hello World !\nJe m'appelle Josué\nJ'aime programmer avec R")
## Hello World !
## Je m'appelle Josué
## J'aime programmer avec R

Dans la suite de cette formation, nous verrons plusieurs autres manières d’utiliser la fonction print() pour afficher des résultats.

R peut être utilisés comme une simple calculatrice. Le tableau ci-dessous montre les symboles des opérateurs basiques dans R :

Opération Symbole
Addition +
Soustraction -
Multiplication *
Division /
Exponentiel ^
Modulo %%
# Addition

8 + 7
## [1] 15
# Soustraction

9 - 4
## [1] 5
# Multiplication

3 * 8
## [1] 24
# Division

100 / 5
## [1] 20
# Exponentiel

3 ^ 2 # 3 ^ 2 se lit 3 puissance 2 et équivaut à 3 fois 3
## [1] 9
# Opérateur modulo : il retourne le reste de la division

18 %% 7 
## [1] 4

18 divisé par 7 est égal à 2 et il reste 4.

L’ordre de priorité des différents opérateurs dans R est le même qu’en Mathématiques :

(7 + 4) * -5
## [1] -55

Dans le cacul ci-dessus, R a d’abord évalué ce qui est entre parenthèses c’est-à-dire 7 + 4 ce qui est égal à 11 puis multiplié 11 par -5 ce qui est effectivement égal à -55.

Le même calcul sans les parenthèses aurait donné comme résultat :

7 + 4 * -5
## [1] -13

Dans le calcul ci-dessus, R a d’abord évalué 4 * -5 ce qui est égal à -20 puis additionné -20 et 7 ce qui est effectivement égal à -13. La multilication est prioritaire sur l’addition et la soustraction.

(2 * 3) ^ 2
## [1] 36

Le même calcul sans les parenthèses donnerait comme résultat :

2 * 3 ^ 2
## [1] 18

R a d’abord évalué 3 ^ 2 (3 puissance 2) ce qui est égal à 9 puis multiplié le résultat par 2 ce qui est égal à 18. La puissance est prioritaire sur la multiplication

4.1.1 Exercice d’application

En une seule ligne de code (utilisez des parenthèses), effectuez les opérations suivantes :

  • Calculez 4 puissance 2 ;

  • Ajoutez 10 au résultat ;

  • Multipliez le résultat par 3.

Vous devez obtenir 78.

((4 ^ 2) + 10) * 3
## [1] 78

4.2 Concept de variable

Dans R, les variables sont définies par le symbole <- ou le symbole =. Dans la suite de ce livre, nous utiliserons le symbole <- pour définir les variables.

# Définition d'une variable y qui est égale à 5

y = 5

# Affichage de la variable y

y # On peut aussi écrire : print(y)
## [1] 5
# Utilisation de la variable y

y * 10
## [1] 50

Il est possible d’utiliser une variable avec la fonction paste() à l’intérieur d’une phrase :

paste("Marc a", y, "ans")
## [1] "Marc a 5 ans"

4.2.1 Exercice d’application

Quelle est la valeur de la variable x après les étapes ci-dessous :

  • Affecte 88 à la variable x

  • Affecte x + 2 à la variable x

  • Affecte x divisé par 3 à la variable x

  • Affecte x puissance 2 à la variable x

#Affecte 88 à la variable x
x <- 88
print(x)
## [1] 88
# Affecte x + 2 à la variable x
x <- x + 2
print(x)
## [1] 90
# Affecte x divisé par 3 à la variable x
x <- x / 3
print(x)
## [1] 30
# Affecte x puissance 2 à la variable x
x <- x ^ 2
print(x)
## [1] 900

Dans le script ci-dessus, la variable x est passée d’une valeur de 88 à finalement une valeur de 900. Ceci pour illustrer le fait qu’une variable peut changer de valeur au cours de l’exécution d’un script d’où le nom variable.

4.3 Types basiques de données.

Les types basiques de données dans R sont : numeric, integer, logical et character. La fonction class est une fonction très utile qui permet de connaître le type des données.

# Variable a

a <- 7.5

class(a)
## [1] "numeric"

Les données de type numeric sont des données décimales.

# Variable b

b <- 4

class(b)
## [1] "numeric"
# Variable c

c <- FALSE

class(c)
## [1] "logical"
# Variable d

d <- "R Programming"

class(d)
## [1] "character"

4.4 Autres types de données

4.4.1 Vecteurs

Pour créer un vecteur dans R, on utilise la fonction c() :

# Vecteur de valeurs numériques

valeurs_num <- c(28, 31, 2021)

print(valeurs_num)
## [1]   28   31 2021
print(class(valeurs_num))
## [1] "numeric"
# Un vecteur peut contenir plusieurs types de données

multi_types <- c(FALSE, "Afrique", 10, "45.6")

print(multi_types)
## [1] "FALSE"   "Afrique" "10"      "45.6"
print(class(multi_types))
## [1] "character"

Dans l’ordre d’importance des types basiques de données, les chaînes de caractères sont en première position. Il peut même avoir un vecteur dans un vecteur :

# Un vecteur à l'intérieur d'un autre vecteur

multi2_types <- c(FALSE, "Afrique", 10, "45.6", c(TRUE, 40))

print(multi2_types)
## [1] "FALSE"   "Afrique" "10"      "45.6"    "1"       "40"
print(class(multi2_types))
## [1] "character"

Soit le vecteur ci-dessous dans lequel est stocké le revenu (en $) perçu par un Data Scientist Consulant pour chaque mois de l’année 2020 :

# Stockage de 12 mois de revenus

revenus <- c(2000, 1500, 3000, 4500, 6000, 5600, 
             2800, 7000, 2200, 800, 11000, 1300)

revenus
##  [1]  2000  1500  3000  4500  6000  5600  2800  7000  2200   800 11000  1300

Pour mieux comprendre le vecteur ci-dessus, nous pouvons ajouter les mois :

# Vecteur des mois de l'année

mois <- c('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 
          'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre',
          'Novembre', 'Décembre')

names(revenus) <- mois

print(revenus)
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2000      1500      3000      4500      6000      5600      2800      7000 
## Septembre   Octobre  Novembre  Décembre 
##      2200       800     11000      1300

Le nouvel affichage du vecteur salaires est meilleur que l’ancien. La fonction names() est une fonction utilisée pour obtenir ou définir les noms d’un objet.

# Obtention des noms du vecteur : revenus

names(revenus)
##  [1] "Janvier"   "Février"   "Mars"      "Avril"     "Mai"       "Juin"     
##  [7] "Juillet"   "Août"      "Septembre" "Octobre"   "Novembre"  "Décembre"

Il est possible d’opérer des opérations avec des vecteurs. Supposons que le Data Scientist Consultant (exemple précédent) a un bonus mensuel de 200$. Mettons alors à jour, le vecteur qui stocke ses revenus :

# Mise à jour du vecteur : revenus

revenus <- revenus + 200

revenus
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500

Le calcul s’est fait élément par élément. Ainsi, 200$ a été ajouté à chacun des 12 revenus.

De la même manière, la somme de deux vecteurs donne un nouveau vecteur composé de la somme élément par élément. Par exemple la somme des vecteurs c(1, 2, 3) et c(4, 5, 6) donne le vecteur c(1 + 4, 2 + 5, 3 + 6) soit c(5, 7, 9).

c(1, 2, 3) + c(4, 5, 6)
## [1] 5 7 9

Calculons le revenu annuel de ce Data Scientist Consultant :

# Total des revenus

total <- sum(revenus)

print(total)
## [1] 50100

Calculons son revenu moyen mensuel

# Revenu moyen mensuel

revenu_moyen <- mean(revenus)

print(revenu_moyen)
## [1] 4175

Quel est le montant de ses revenus en Avril ?

Dans R, la numérotation d’indices commence à partir de 1. Donc, Avril est d’indice n°4.

# Revenu d'avril

revenu_avril <- revenus[4]

revenu_avril
## Avril 
##  4700

On peut aussi écrire :

# Revenu d'avril

revenus["Avril"]
## Avril 
##  4700

On peut aussi récupérer, en une seule ligne code, les revenus de plusieurs mois :

# Vecteur des revenus de Février, Mars et Juillet

vect_rev <- revenus[c("Février", "Mars", "Juillet")]

vect_rev
## Février    Mars Juillet 
##    1700    3200    3000

On peut aussi écrire :

revenus[c(2, 3, 7)]
## Février    Mars Juillet 
##    1700    3200    3000
# Revenus de Février à Août

revenus[2:8]
## Février    Mars   Avril     Mai    Juin Juillet    Août 
##    1700    3200    4700    6200    5800    3000    7200

4.4.2 Matrices

Une matrice est une collection d’éléments de même type rangés en un nombre fixe de lignes et de colonnes. Dans R, c’est la fonction matrix() qui permet de créer une matrice.

# Exemple de matrice

matrice <- matrix(data = 11:19, byrow = TRUE, nrow = 3)

print(matrice)
##      [,1] [,2] [,3]
## [1,]   11   12   13
## [2,]   14   15   16
## [3,]   17   18   19
class(matrice)
## [1] "matrix" "array"
  • L’argument data est la collection d’éléménts à arranger en lignes et colonnes de la matrice. Soulignons que le code 11:19 est équivalent au code c(11, 12, 13, 14, 15, 16, 17, 18, 19);

  • byrow = TRUE signifie que la matrice a été remplie par des éléments en ligne ;

  • row = 3 signifie que la matrice sera constituée de 3 lignes.

4.4.2.1 Exercice d’application

A partir du vecteur revenus défini plus haut, créez une matrice de 4 lignes et 3 colonnes.

mat_revenus <- matrix(revenus, byrow = TRUE, ncol = 3)

mat_revenus
##      [,1]  [,2] [,3]
## [1,] 2200  1700 3200
## [2,] 4700  6200 5800
## [3,] 3000  7200 2400
## [4,] 1000 11200 1500

De la même manière qu’il est possible de nommer des éléments dans un vecteur, il est aussi possible de nommer les lignes et les colonnes d’une matrice. en utilisant respectivement les fonctions rownames() et colnames().

# Noms des lignes et colonnes d'une matrice

rownames(mat_revenus) <- c("ligneA", "ligneB", "ligneC", "ligneD")

colnames(mat_revenus) <- c("colA", "ColB", "colC")

mat_revenus
##        colA  ColB colC
## ligneA 2200  1700 3200
## ligneB 4700  6200 5800
## ligneC 3000  7200 2400
## ligneD 1000 11200 1500

Effectuons quelques opérations avec les matrices. La fonction rowSums() permet de calculer la somme de chaque ligne d’une matrice et le résultat est stocké dans un nouveau vecteur :

# Calcul de la somme de chaque ligne d'une matrice

rowSums(mat_revenus)
## ligneA ligneB ligneC ligneD 
##   7100  16700  12600  13700

La fonction colSums() permet de calculer la somme de chaque colonne d’une matrice et le résultat est stocké dans un nouveau vecteur.

# Calcul de la somme de chaque colonne d'une matrice

colSums(mat_revenus)
##  colA  ColB  colC 
## 10900 26300 12900

De la même manière qu’avec les vecteurs, les opérations basiques dans une matrice se font élément par élément.

# Division dans une matrice

mat_revenus / 3
##             colA      ColB     colC
## ligneA  733.3333  566.6667 1066.667
## ligneB 1566.6667 2066.6667 1933.333
## ligneC 1000.0000 2400.0000  800.000
## ligneD  333.3333 3733.3333  500.000
# Multiplication dans une matrice

mat_revenus * 10
##         colA   ColB  colC
## ligneA 22000  17000 32000
## ligneB 47000  62000 58000
## ligneC 30000  72000 24000
## ligneD 10000 112000 15000
# Moyenne

mean(mat_revenus)
## [1] 4175

L’une des compétences majeures en Analyse de données est la capacité de séletionner un ou plusieurs éléments d’une matrice. Dans les codes ci-dessous, nous montrons comment récupérer des éléments de la matrice mat_revenus :

# Elément à la première ligne et la deuxième colonne : 1700

mat_revenus[1, 2]
## [1] 1700
# Tous les éléménts de la troisième colonne

mat_revenus[,3]
## ligneA ligneB ligneC ligneD 
##   3200   5800   2400   1500
# Matrice des élements des 1ère, 2è, 3è ligne ainsi que des 2è et 3è colonnes

mat_revenus[1:3, 2:3]
##        ColB colC
## ligneA 1700 3200
## ligneB 6200 5800
## ligneC 7200 2400

4.4.3 Dataframe

Dans une dataframe, les données se présentent sous formes de tableau (lignes et colonnes). Plus précisément, dans une dataframe on parle d’observations (pour désigner les lignes) et de variables (pour désigner les colonnes). Une dataframe se présente comme les tableaux de données dans des logiciels tels que Excel, SAS, SPSS ainsi comme les tables dans les bases de données relationnelles.

R contient de manière intrinsèque quelques dataframes. On peut citer par exemple la dataframe iris :

##    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
## 6           5.4         3.9          1.7         0.4  setosa
## 7           4.6         3.4          1.4         0.3  setosa
## 8           5.0         3.4          1.5         0.2  setosa
## 9           4.4         2.9          1.4         0.2  setosa
## 10          4.9         3.1          1.5         0.1  setosa
class(iris)
## [1] "data.frame"

Les fonctions head() et tail() permettent d’afficher respectivement les premières et les dernières lignes d’une dataframe. Par défaut, elles affichent 5 lignes :

 # Cinq premières lignes de la dataframe : iris

head(iris)
##   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
## 6          5.4         3.9          1.7         0.4  setosa
# 8 premières lignes de la dataframe iris

head(iris, 8)
##   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
## 6          5.4         3.9          1.7         0.4  setosa
## 7          4.6         3.4          1.4         0.3  setosa
## 8          5.0         3.4          1.5         0.2  setosa
# Cinq dernières lignes de la dataframe iris

tail(iris)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 145          6.7         3.3          5.7         2.5 virginica
## 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
# 8 dernières lignes de la dataframe iris

tail(iris, 8)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 143          5.8         2.7          5.1         1.9 virginica
## 144          6.8         3.2          5.9         2.3 virginica
## 145          6.7         3.3          5.7         2.5 virginica
## 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

Pour avoir un aperçu global de la structure d’une dataframe, vous pouvez utilisez la fonction str() :

# Structure de la dataframe iris

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

Ce résultat permet d’avoir plusieurs types d’informations importantes sur la dataframe iris :

  • Nombre d’observations (lignes) et de variables (colonnes) ;

  • Les types de valeurs dans chaque variable. Toutes les variables de la dataframe iris sont numériques sauf la variable ‘Species’ qui est catégorielle.

Pour créer une dataframe dans R, vous pouvez utiliser la fonction data.frame :

# Création d'une dataframe

anglais <- c(18, 12, 14.5, 17, 20, 19.75, 10)

maths <- c(9, 11.25, 20, 16, 13, 20, 7.5)

variables <- c('Anglais', 'Maths')

notes <- data.frame(anglais, maths)

print(notes)
##   anglais maths
## 1   18.00  9.00
## 2   12.00 11.25
## 3   14.50 20.00
## 4   17.00 16.00
## 5   20.00 13.00
## 6   19.75 20.00
## 7   10.00  7.50
print(class(notes))
## [1] "data.frame"

La dataframe notes stocke les résultats obtenus par 7 élèves en Anglais et en Mathématiques. L’une des tâches les plus fréquentes en analyse de données est le calcul des statistiques descriptives d’un ensemble de données. Pour afficher le résumé statistique d’une dataframe, vous pouvez utiliser la fonction summary() :

# Résumé statistique

print(summary(notes))
##     anglais          maths      
##  Min.   :10.00   Min.   : 7.50  
##  1st Qu.:13.25   1st Qu.:10.12  
##  Median :17.00   Median :13.00  
##  Mean   :15.89   Mean   :13.82  
##  3rd Qu.:18.88   3rd Qu.:18.00  
##  Max.   :20.00   Max.   :20.00
print(class(summary(notes)))
## [1] "table"

De la même manière qu’avec les vecteurs et les matrices, la sélection d’éléments d’une dataframe se fait en utilisant les crochets [] :

# Note obtenue en Anglais par le quatrième élève (4è ligne et 1ère colonne)

notes[4, 1]
## [1] 17
# Deuxième ligne de la dataframe iris

iris[2,]
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 2          4.9           3          1.4         0.2  setosa
# Les 5 premières notes en Maths

notes[1:5, "maths"]
## [1]  9.00 11.25 20.00 16.00 13.00
# Sélection de la colonne 'anglais' de la dataframe notes

notes$anglais
## [1] 18.00 12.00 14.50 17.00 20.00 19.75 10.00

La filtration est une opération très utilisée pour mieux comprendre les données et en tirer des informations utiles. Dans R, on peut utiliser la fonction subset() pour filtrer les données :

# Sélection des élèves dont les notes en anglais sont supérieures à 15 

subset(notes, anglais > 15)
##   anglais maths
## 1   18.00     9
## 4   17.00    16
## 5   20.00    13
## 6   19.75    20

La dataframe constitue la structure de données la plus utilisée en Data Science. Nous y reviendrons dans les prochains chapitres afin de voir d’autres manières de les manipuler.

4.4.4 Liste

La liste est une des structure de données qui peut contenir des chaînes de caractères, des nombres, des booléens, des dataframes, d’autres listes ainsi que d’autres types de structure de données. La fonction list() permet de créer une liste dans R.

# Exemple de liste

courses <- list('farine de blé', 'pâtes', 'lait', 'légumes')

print(courses)
## [[1]]
## [1] "farine de blé"
## 
## [[2]]
## [1] "pâtes"
## 
## [[3]]
## [1] "lait"
## 
## [[4]]
## [1] "légumes"
print(class(courses))
## [1] "list"

Une liste peut contenir plusieurs types de données. La liste ci-dessous contient un vecteur, une matrice, la dataframe iris (5 premières lignes) ainsi qu’une autre liste :

# Liste constituée d'un vecteur et d'une matrice

liste_mixte <- list(revenus, matrice, head(iris), courses)

print(liste_mixte)
## [[1]]
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500 
## 
## [[2]]
##      [,1] [,2] [,3]
## [1,]   11   12   13
## [2,]   14   15   16
## [3,]   17   18   19
## 
## [[3]]
##   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
## 6          5.4         3.9          1.7         0.4  setosa
## 
## [[4]]
## [[4]][[1]]
## [1] "farine de blé"
## 
## [[4]][[2]]
## [1] "pâtes"
## 
## [[4]][[3]]
## [1] "lait"
## 
## [[4]][[4]]
## [1] "légumes"
print(class(liste_mixte))
## [1] "list"

Comme pour les vecteurs, il est possible de nommer les différents éléments d’une liste.

# Noms des éléments de la liste : liste_mixte

names(liste_mixte) <- c('Revenus', 'Matrice', 
                        'Dataframe iris', 
                        'Liste de courses')

print(liste_mixte)
## $Revenus
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500 
## 
## $Matrice
##      [,1] [,2] [,3]
## [1,]   11   12   13
## [2,]   14   15   16
## [3,]   17   18   19
## 
## $`Dataframe iris`
##   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
## 6          5.4         3.9          1.7         0.4  setosa
## 
## $`Liste de courses`
## $`Liste de courses`[[1]]
## [1] "farine de blé"
## 
## $`Liste de courses`[[2]]
## [1] "pâtes"
## 
## $`Liste de courses`[[3]]
## [1] "lait"
## 
## $`Liste de courses`[[4]]
## [1] "légumes"

Grâce à l’indexation, on peut récupérer un ou plusieurs éléments d’une liste :

# Premier élément de la liste : courses

courses[[1]]
## [1] "farine de blé"
# Troisième élémént de la liste : courses

courses[[3]]
## [1] "lait"

Vous pouvez aussi vous référez aux noms des éléments d’une liste en utilisant le symbole $ ou [[]] :

liste_mixte$Revenus
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500
liste_mixte[["Revenus"]]
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500

Pour récupérer le deuxième élément de la liste courses à partir de la liste liste_mixte :

liste_mixte[['Liste de courses']][[2]]
## [1] "pâtes"

ou encore :

liste_mixte$`Liste de courses`[[2]]
## [1] "pâtes"

5 Chapitre 2 : Structures conditionnelles et Boucles

5.1 Boléens et Opérateurs logiques

Les booléens sont : TRUE et FALSE.

# Variables booléennes

majeur <- TRUE

print(majeur)
## [1] TRUE
print(class(majeur))
## [1] "logical"
senior <- FALSE

print(senior)
## [1] FALSE
print(class(senior))
## [1] "logical"

Le tableau ci-dessous présente quelques opérateurs logiques dans R :

Opérateur Signification
& et
| ou
!x Négation de x
isTRUE(x) Test si x est vraie
isFALSE(x) Test si x est faux
# Combinaisons des booléens et des opérateurs logiques

paste("vrai et vrai :", TRUE & TRUE) 
## [1] "vrai et vrai : TRUE"
paste("vrai et faux :", TRUE & FALSE) 
## [1] "vrai et faux : FALSE"
paste("faux et vrai :", FALSE & TRUE) 
## [1] "faux et vrai : FALSE"
paste("vrai ou vrai :", TRUE | TRUE) 
## [1] "vrai ou vrai : TRUE"
paste("Tvrai ou faux :", TRUE | FALSE) 
## [1] "Tvrai ou faux : TRUE"
paste("faux ou vrai :", FALSE | TRUE) 
## [1] "faux ou vrai : TRUE"
paste("faux ou faux :", FALSE | FALSE) 
## [1] "faux ou faux : FALSE"
paste("Négation de vrai :", !TRUE) 
## [1] "Négation de vrai : FALSE"
paste("Négation de faux :", !FALSE)
## [1] "Négation de faux : TRUE"
paste("Est-ce que la variable majeur est égale à faux ? :",
      isFALSE(majeur))
## [1] "Est-ce que la variable majeur est égale à faux ? : FALSE"
paste("Est-ce que la variable majeur est égale à vrai ? :",
      isTRUE(majeur))
## [1] "Est-ce que la variable majeur est égale à vrai ? : TRUE"

5.1.1 Exercice d’application

Considérez les variables majeur et senior définies plus haut. Sans écrire le code, quel est le résultat de :

  • majeur et senior

  • majeur ou senior

  • non majeur

  • non senior

  • non majeur et non senior

  • non majeur ou non senior

Vérifiez vos résultats en écrivant le code.

# Correction

paste("majeur et senior :", majeur & senior)
## [1] "majeur et senior : FALSE"
paste("majeur ou senior :", majeur | senior)
## [1] "majeur ou senior : TRUE"
paste("non majeur :", !majeur)
## [1] "non majeur : FALSE"
paste("non senior :", !senior)
## [1] "non senior : TRUE"
paste("non majeur et non senior :", !majeur & !senior)
## [1] "non majeur et non senior : FALSE"
paste("non majeur ou non senior :", !majeur | !senior)
## [1] "non majeur ou non senior : TRUE"

5.2 Opérateurs de comparaison

Les opérateurs de comparaison, encore appelés opérateurs relationnels, permettent de comparer les objets. Les réponses de ces comparaisons sont des booléens (TRUE ou FALSE). Le tableau ci-dessous montre les différents opérateurs de comparaison qu’on retrouve dans R :

Symbole Signification
< Inférieur à
> Supérieur à
<= Inférieur ou égal
>= Supérieur ou égal
== Equivalent à
!= Différent de
# Comparaison de booléens

print(TRUE == FALSE)
## [1] FALSE
print(TRUE != FALSE)
## [1] TRUE
print(TRUE > FALSE)
## [1] TRUE

En effet, TRUE a la valeur de 1 et FALSE est égal à 0.

# Comparaison de chaînes de caractères

print('paris' > 'limoges')
## [1] TRUE

En effet, R utilise l’ordre alphabétique pour trier les chaînes de caractères. Etant donné que ‘p’ vient après ‘l’ dans l’alphabet, alors ‘paris’ est considéré comme supérieur à ‘limoges’.

# Opérateurs de comparaison et vecteurs

print(revenus)
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##      2200      1700      3200      4700      6200      5800      3000      7200 
## Septembre   Octobre  Novembre  Décembre 
##      2400      1000     11200      1500
print(revenus > 4000)
##   Janvier   Février      Mars     Avril       Mai      Juin   Juillet      Août 
##     FALSE     FALSE     FALSE      TRUE      TRUE      TRUE     FALSE      TRUE 
## Septembre   Octobre  Novembre  Décembre 
##     FALSE     FALSE      TRUE     FALSE

Le code revenus > 4000 permet de connaître les mois où le revenu de ce Data Scientist Consultant (Voir Chapitre 1) est supérieur à 4000 dollars. Il s’agit des mois d’Avril, Mai, Juin, Août et Novembre où on a TRUE.

Les opérateurs de comparaison permettent aussi d’affiner la sélection des données dans une dataframe au moyen de la filtration. Par exemple, si nous voulons connaître les élèves dont la note en maths est supérieure à 12 et la note en anglais est supérieure à 15, nous pouvons écrire le code ci-dessous :

# Filtration combinée avec un opérateur relationnel

subset(notes, anglais > 15 & maths > 12)
##   anglais maths
## 4   17.00    16
## 5   20.00    13
## 6   19.75    20

Il y a trois élèves qui respectent les conditions citées ci-dessus.

Les opérateurs de comparaison sont très utilisés en programmation informatique particulièrement au sein des structures conditionnelles comme les structures if.

5.3 Structure conditionnelle if

Les conditions évaluent les expressions booléennes et elles sont généralement précédées par le mot clé if. La synthaxe d’une déclaration if se présente comme ci-dessous :

# Synthaxe de la structure if

if (condition) {
  
  instruction
  
}

L’instruction if prend une condition (la condition est écrite entre parenthèses) ; Si la condition est évaluée comme étant vraie (TRUE) alors le code R associé à l’instruction (l’instruction est écrite entre accolades) est exécuté.

# Exemple de structure if

a <- 3

if (a > 0) {
  
  print("a est un nombre positif")
  
}
## [1] "a est un nombre positif"

La condition a > 0 est évaluée comme étant vraie (TRUE) car a est égal à 3 et 3 est supérieur à 0. Donc le code print("a est un nombre positif") a été exécuté. Changeons la valeur de a et réexécutons le code ci-dessus :

a <- -5

if (a > 0) {
  print("a est un nombre positif")
}

En exécutant le code ci-dessus, rien ne s’affiche car la condition a > 0 a été évalué comme étant fausse (FALSE) donc le code print("a est un nombre positif") n’a pas été exécuté. Ceci nos amène au moté clé else. else s’utilise avec une structure if et permet d’exécuter le code associé à une instruction chaque fois que la condition du test if n’est pas satisfaite.

# Synthaxe d'une structure if...else

if (condition) {
  
  instruction 1
  
} else {
  
  instruction 2
  
}

Reprenons l’exemple précédent tout en ajoutant un else :

a <- -5

if (a > 0) {
  
  print("a est un nombre positif")
  
} else {
  
  print("a est null ou a est un nombre négatif") 
  
}
## [1] "a est null ou a est un nombre négatif"

Cette fois-ci, l’instruction du else c’est-à-dire le code print("a est un nombre négatif") a été exécuté car la condition du if est évaluée comme étant fausse.

Il est possible de tester une deuxième condition en utilisant else if. else if se place entre le if et le else :

# Syntaxe if...else if...else

if (condition 1) {
  
  instruction 1
  
} else if (condition 2) {
  
  instruction 2
  
} else {
  
  instruction 3
  
}

Dans l’exemple précédent, ajoutons une nouvelle condition pour tester si a est nul.

a <- 0

if (a > 0) {
  
  print("a est un nombre positif")
  
} else if (a == 0) {
  
   print("a est égal à zéro")
  
} else {
  
  print("a est un nombre négatif")
  
}
## [1] "a est égal à zéro"

R vérifie d’abord la condition du if. Ici cette condition est évaluée comme étant fausse. R passe donc à la vérification de la condition du else if. Ici cette condition est évaluée comme étant vraie car est a est égal à 0. Le programme s’arrête donc à ce niveau et le code print("a est égal à zéro") est exécuté.

En définitive, dès que R tombe sur une condition qui est évaluée comme étant vraie, R exécute le code correspondant puis ignore le reste de la structure de contrôle.

5.3.1 Exercice d’application

Dans un pays, pour être autoriser à voter il faut avoir au minimum 18 ans et pour être autoriser à jouer aux jeux de hasard il faut avoir au minimum 25 ans. Ecrivez un petit programme qui indique si une personne, en fonction de son âge, peut voter ou pas et s’il peut jouer aux jeux de hasard ou pas.

# Correction

age <- 15

if (age >= 25) {
  
  print("Vous pouvez voter et jouer au jeu de hasard")
  
} else if (age >= 18) {
  
  print("Vous pouvez voter")
  
} else {
  
  print("Patitentez ! Vous êtes encore très jeune !")
  
}
## [1] "Patitentez ! Vous êtes encore très jeune !"

5.4 Boucle for

En programmation, les boucles permettent de faire des itérations, c’est-à-dire de répéter un nombre de fois donné le même bloc d’instructions. Il existe 02 types de boucles : les boucles while et le boucles for.

Avec les boucles for, on peut itérer sur les nombres, les chaînes de caractères et sur d’autres objets itérables et on connaît le nombre de fois que l’instruction est répété.

# Synthaxe d'une boucle for dans R

for (var in seq) {
  
  instruction
  
}

Le code ci-dessus signifie : Pour tout élément var dans la séquence seq, exécutez l’instruction (instruction). Analysons l’exemple ci-dessous :

outils <- list('R', 'Shiny', 'Python', 
               'Excel', 'Power Bi', 'Tableau', 
               'SAS', 'STATA', 'SPSS')

for (logiciel in outils) {
  
  print(paste('Diana est Formatrice en', logiciel))
  
}
## [1] "Diana est Formatrice en R"
## [1] "Diana est Formatrice en Shiny"
## [1] "Diana est Formatrice en Python"
## [1] "Diana est Formatrice en Excel"
## [1] "Diana est Formatrice en Power Bi"
## [1] "Diana est Formatrice en Tableau"
## [1] "Diana est Formatrice en SAS"
## [1] "Diana est Formatrice en STATA"
## [1] "Diana est Formatrice en SPSS"

Comme vous le constatez plus haut, la boucle for permet d’itérer sur un objet itérable (une liste par exemple) et répète une ou plusieurs instructions.

# Autre exemple : Affichez une table de multiplication par 3

for (i in 0:10) {
  
  print(paste(3, "X", i, "=", 3 * i))
  
}
## [1] "3 X 0 = 0"
## [1] "3 X 1 = 3"
## [1] "3 X 2 = 6"
## [1] "3 X 3 = 9"
## [1] "3 X 4 = 12"
## [1] "3 X 5 = 15"
## [1] "3 X 6 = 18"
## [1] "3 X 7 = 21"
## [1] "3 X 8 = 24"
## [1] "3 X 9 = 27"
## [1] "3 X 10 = 30"

Les boucles for constituent un outil puissant pour répéter des instructions et donc ne pas écrire beaucoup de lignes de codes.

# Autre exemple : boucle for avec condition if

for (i in c('a', 'b', 'c')) {
  
  if (i != 'a' & i != 'c') {
    
    print(i)
    
  }
  
}
## [1] "b"

Dans l’exemple ci-dessus, i peut prendre les valeurs ‘a’, ‘b’ et ‘c’. La seule valeur qui permet de satisfaire la condition i != 'a' & i != 'c' (i différent de ‘a’ et i différent de ‘c’) est ‘b’.

5.4.1 Exercice d’application

A l’aide d’une boucle for, écrivez un code pour obtenir la suite de chiffres suivants : 20, 18, 16, 14, 12, 10, 8, 6, 4, 2 et 0

# Correction

for (i in seq(20, 0, -2)) {
  
  print(i)
  
}
## [1] 20
## [1] 18
## [1] 16
## [1] 14
## [1] 12
## [1] 10
## [1] 8
## [1] 6
## [1] 4
## [1] 2
## [1] 0

5.5 Boucle while

Contrairement à la boucle for, la boucle while est une boucle conditionnelle, utilisée lorsqu’on ne connait pas d’avance le nombre de fois que l’instruction devra être exécutée.

# Synthaxe d'une boucle while

Initialisation

while (condition) {
  
  instruction
  
  incrementation
  
}

Considérons l’exemple ci-dessous :

 # Affichage des dix premiers entiers naturels : 0, 1, 2, 3, 4, 5, 6, 7, 8 et 9

i = 0

while (i < 10) {
  
  print(i)
  
  i <- i + 1
  
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9

Dans l’exemple ci-dessus, la variable i a été initialisé à 0. Le code écrit signifie : tant que i est strictement inférieur à 10, affichez i et incrémentez-le au pas 1.

N.B : il est très important de bien vérifier le code d’une boucle while avant de l’exécuter. En effet, si ce code est mal écrit (mauvaise initialisation ou mauvaise condition ou encore mauvaise incrémentation), la boucle peut s’exécuter indéfiniment et donc saturer la mémoire de l’ordinateur.

Il est possible de forcer l’arrêt d’une boucle while en utilisant le mot clé break :

            # While avec break

# initialisation
i = 1 

while (i <= 10) {
  
  # Condition d'arrêt de la boucle
  if (i == 6) {
    
    break #cmot clé pour stopper la boucle
    
  }
  
  # Instruction
  print(i)
  
  # incrémentation
  i <- i + 1
  
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5

Dans le code de l’exemple ci-dessus, tant que i est inférieur à 10, affichez i et incrémentez-le au pas 1. Si à un moment donné i prend la valeur 6 alors STOPPEZ (break) la boucle. break permet donc de forcer l’arrêt d’une boucle while malgré que la condition soit toujours évaluée comme étant vraie.

5.5.1 Exercice d’application

Ecrire une boucle while pour afficher les nombres de 0 à 50 en allant par pas de 5.

# Correction

i = 0

while (i <= 50) {
  
  print(i)
  
  i <- i + 5
  
}
## [1] 0
## [1] 5
## [1] 10
## [1] 15
## [1] 20
## [1] 25
## [1] 30
## [1] 35
## [1] 40
## [1] 45
## [1] 50

Dans cette deuxième partie du livre, vous apprendrez entres autres à :

  • utiliser les fonctions de la famille apply tels que lapply(), sapply() et vapply() ;

  • créer vos propres fonctions et les optimiser afin d’automatiser certaines tâches et rendre votre code réutilisable ;

  • créer des listes de compréhension vous permettant d’écrire des boucles for plus ou moins complexes en une seule ligne de code ;

  • importer différents types de fichiers tels que Excel, CSV, txt, TSV, …;

  • importer des données provenant du web à partir des API (Application Programing Interface) et du WebScraping ;

  • Etc.

6 Chapitre 3 : Fonctions

6.1 Généralités

Les fonctions constituent un important concept en programmation informatique. Dans ce chapitre, vous apprendrez à créer vos propres fonctions et à les utiliser.

Il existe des milliers de fonctions intrinsèques (c’est-à-dire préconstruites) dans R comme certaines fonctions que nous avons déjà utilisé depuis le début de ce livre. Au nombre de celles-ci, on peut citer les fonctions print(), paste(), matrix, c(), etc.

Pour avoir la documentation d’une fonction, vous pouvez utiliser la fonction help().

# Exemple : documentation de la fonction matrix

help("matrix")

Les arguments sont les paramètres d’entrée d’une fonction.

# Exemple : Arguments de la fonction matrix()

args(matrix)
## function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
## NULL

Comme vous le constatez ci-dessus, certains arguments ont des valeurs par défaut. Par exemple les arguments nrow et ncol sont par défaut égaux à 1. Donc, si ces arguments ne sont pas précisés lors de l’utilisation de la fonction matrix(), R considère leurs valeurs par défaut.

Il est possible d’avoir une fonction à l’intérieur d’une autre fonction : Fonctions imbriquées

# Exemple de fonctions imbriquées

v1 <- c(15, 5, 6, 8, 0, 80)

v2 <- c(7, 2, 100, 20, 25, 33)

mean(abs(v2 - v1))
## [1] 31.5

Le code abs(v2 - v1) retourne le vecteur composé des valeurs absolues du vecteur v2 - v1. Le code mean(abs(v2 - v1)) calcule la moyenne de ce vecteur. Donc en une seule ligne de code, il est possible d’effectuer des opérations plus ou moins complexes.

6.2 Construction d’une fonction

Pour réaliser des tâches spécifiques, il est souvent nécessaire de créer soi-même sa propre fonction. L’intérêt d’écrire une fonction réside dans le fait de ne pas copier/coller du code. Une fonction est comme une boîte noire, c’est-à-dire qu’elle prend des paramètres en entrée et génèrent des sorties sans que les utilisateurs n’aient à se soucier de ce qui se passe à l’intérieur de la fonction.

# Syntaxe d'une fonction 

ma_fonction <- function(argument1, argument2) {
  
  corps de la fonction
  
}

Le code ci-dessus montre la syntaxe d’une fonction. La fonction ma_fonction prend 02 arguments argument1 et argument2 et exécute le code à l’intérieur des acolades (corps de la fonction) puis génère éventuellement une sortie.

Soit la fonction ci-dessous qui n’a pas d’arguments :

# Fonction sans arguments

bonjour <- function() {
  
  cat("Bonjour Madame/Monsieur\nComment allez-vous ?")
  
}
# Utilisation (Appel) de la fonction

bonjour()
## Bonjour Madame/Monsieur
## Comment allez-vous ?

Et si vous voulez plutôt saluer une personne en particulier en mentionnant son nom ? On peut par exemple remplacer Madame/Monsieur par le nom de la personne, Diana par exemple. Pour saluer une autre personne qui ne s’appelle pas Diana, comment faire ? Il suffit juste de mettre un argument dans votre fonction qui permettra de la généraliser.

# Fonction avec un argument

Bonjour <- function(prenom) {
  
  cat(paste("Bonjour", prenom, "\nComment allez-vous ?"))
  
}
Bonjour("Hairia")
## Bonjour Hairia 
## Comment allez-vous ?
Bonjour("Josué")
## Bonjour Josué 
## Comment allez-vous ?

Modifions la fonction Bonjour() en y ajoutant un deuxième argument : le nom.

# Fonction avec deux arguments

Bonjour <- function(prenom, nom) {
  
  cat(paste("Bonjour", prenom, nom, "\nComment allez-vous ?"))
  
}
Bonjour("Josué", "Afouda")
## Bonjour Josué Afouda 
## Comment allez-vous ?

Créons une fonction qui calcule le double d’un nombre :

double_fonc <- function(x) {
  
  2 * x
  
}

La fonction double_fonc prend un argument x et calcule son double. Utilisons cette fonction pour calculer le double de 100.65 :

# Ici l'argument x est égal à 100.65 et 2 * 100.65 est égal à 201.3

double_fonc(100.65)
## [1] 201.3

Dans une fonction, la dernière expression évaluée est le résultat retourné par cette fonction. Vous pouvez également, de manière explicite, spécifié la valeur de sortie d’une fonction en utilisant le mot clé return :

# Exemple de fonction avec le mote clé return

square <- function(x) {
  
  y <- x^2
  
  # Sortie de la fonction
  return(y)
}
rslt <- square(4)

print(rslt)
## [1] 16

Une fonction peut aussi retourner deux ou plusieurs valeurs :

# Exemple de fonction retournant deux valeurs

soustraction_dans_les_deux_dens <- function(valeur1, valeur2) {
  
  a = valeur1 - valeur2
  
  b = valeur2 - valeur1
  
  resultat = c(a, b)
  
  return(resultat)
  
}
res <- soustraction_dans_les_deux_dens(-8, 17)

print(res)
## [1] -25  25

6.2.1 Exercice d’application

Créez une fonction qui prend deux arguments et retourne la somme de ces derniers si et seulement les deux arguments sont de même type. Si les deux arguments ne sont pas de même type, la fonction doit retourner la phrase : “les arguments ne sont pas de même type”

# Correction

somme <- function(a, b) {
  
  if (class(a) == class(b)) {
    
    return(a + b)
    
  } else {
    
    print("Les deux arguments ne sont pas de même type")
    
  }
  
}
# Vérification de la fonction

somme(5, 7)
## [1] 12

Dans l’exemple ci-dessus, 5 et 7 sont tous deux des entiers naturels d’où le résultat 12 qui est effectivement la somme de 5 et 7.

somme (10, 'R')
## [1] "Les deux arguments ne sont pas de même type"

Dans l’exemple ci-dessus, 10 est un entier naturel et ‘R’ est un caractère donc à ce niveau les arguments ne sont pas de même type d’où le résultat : “Les deux arguments ne sont pas de même type”.

6.3 Liste de compréhension

Les listes de compréhension sont des outils extrêmement pratiques pour les Programmeurs. Elles permettent de créer des listes à partir de boucles for, plus ou moins complexes, en une seule ligne de code simplifiant ainsi votre script en le rendant plus efficace.

Pour créer des listes de compréhension dans R, vous devez préalablement importer la librairie comprehenr :

# Utilisez la fonction install.packages() pour installer une librairie dans R

install.packages("comprenhr")

Chargez maintenant la librairie dans l’environnement de travail :

# Librairie "comprehenr"

library(comprehenr)

Voici un aperçu de la puissance des listes de compréhension :

# Création d'une liste à l'aide d'une boucle for

numeros = list(10, 20, 30, 40, 50)

numeros_carres = list()

for (i in numeros) {
  
  numeros_carres <- append(i^2, numeros_carres)
  
}

print(numeros_carres)
## [[1]]
## [1] 2500
## 
## [[2]]
## [1] 1600
## 
## [[3]]
## [1] 900
## 
## [[4]]
## [1] 400
## 
## [[5]]
## [1] 100

Le code ci-dessus permet de créer une liste composée des carrés des éléments de la liste numeros préalablement définie. A chaque itération, le code calcule le carré d’un élement de la liste numeros et l’enregistre au fur et à mesure dans la liste numeros_carres grâce à la fonction append()

Avec une liste de compréhension, il est possible d’obtenir le même résultat en une seule ligne de code :

# Liste de compréhension

to_list(for(i in numeros) i^2)
## [[1]]
## [1] 100
## 
## [[2]]
## [1] 400
## 
## [[3]]
## [1] 900
## 
## [[4]]
## [1] 1600
## 
## [[5]]
## [1] 2500

On pouvait aussi utiliser la fonction to_vect() pour obtenir le résultat sous forme de vecteur :

to_vec(for(i in numeros) i^2)
## [1]  100  400  900 1600 2500

6.3.1 Exercice d’application

On donne le vecteur : hopital = c('docteur', 'infirmière', 'chercheur', 'medecin', 'chu'). Ecrivez une liste de compréhension qui produit un vecteur composé du premier caractère de chaque élément de la liste hopital.

La fonction substring() permet d’extraire ou de remplacer des caractères (ou chaînes de caractères). Par exemple, le code substring(i, 2, 2) permet d’extraire le deuxième élément de la chaîne de caractère i.

# Correction

hopital <- c('docteur', 'infirmière', 'chercheur', 'medecin', 'chu')

to_vec(for (i in hopital) substring(i, 1, 1))
## [1] "d" "i" "c" "m" "c"

6.4 Fonctions de la famille apply

Les fonctions de la famille apply constituent un outil puissant en programmation avec le langage R. En effet, tout comme les listes de compréhension, elles permettent d’écrire des boucles for plus ou moins complexes en une seule ligne de code.

La première fonction de la famille apply que nous étudierons est lapply. Considérons l’exemple ci-dessous, où une boucle for est utilisée pour connaître la classe de chaque élément d’une liste :

abidjan <- list(population = 4707404, 
                pays = "Côte-d'Ivoire", 
                capitale = FALSE)

for (i in abidjan) {
  
  print(class(i))
  
}
## [1] "numeric"
## [1] "character"
## [1] "logical"

Comme on s’y attendait, le premier élément de la liste abidjan est numérique, le deuxième est une chaîne de caractères et le troisième est un booléen. Avec la fonction lapply(), nous obtenons le même résultat mais en très peu de code :

# Arguments de la fonction lapply()

args(lapply)
## function (X, FUN, ...) 
## NULL

La fonction lapply() renvoie une liste de même longueur que X, dont chaque élément est le résultat de l’application de FUN (l’argument FUN prend une fonction comme valeur) à l’élément correspondant de X.

# Exemple d'utilisation de la fonction lapply

lapply(abidjan, class)
## $population
## [1] "numeric"
## 
## $pays
## [1] "character"
## 
## $capitale
## [1] "logical"

Vous remarquez qu’au niveau du résultat ci-dessus, le nom de chaque élément de la liste est conservé ce qui donne un affichage beaucoup plus compréhensible qu’une simple boucle for.

Soit le vecteur ci-dessous dans lequel est stocké le revenu (en $) perçu par un Data Scientist Consulant pour chaque mois de l’année 2020 :

# Stockage de 12 mois de revenus

revenus <- c(2000, 1500, 3000, 4500, 6000, 5600, 
             2800, 7000, 2200, 800, 11000, 1300)

revenus
##  [1]  2000  1500  3000  4500  6000  5600  2800  7000  2200   800 11000  1300

Il est aussi possible d’utiliser lapply() sur vos propres fonctions :

# Utilisation de la fonction double-fonc pour mutiplier par 2 chaque revenu

print(revenus_lapply <- lapply(revenus, double_fonc))
## [[1]]
## [1] 4000
## 
## [[2]]
## [1] 3000
## 
## [[3]]
## [1] 6000
## 
## [[4]]
## [1] 9000
## 
## [[5]]
## [1] 12000
## 
## [[6]]
## [1] 11200
## 
## [[7]]
## [1] 5600
## 
## [[8]]
## [1] 14000
## 
## [[9]]
## [1] 4400
## 
## [[10]]
## [1] 1600
## 
## [[11]]
## [1] 22000
## 
## [[12]]
## [1] 2600

6.4.1 Exercice d’application

Soit le vecteur ci-dessous composé des noms de certains pays africains :

pays <- c("Bénin", "Côte d'Ivoire", "Ghana", 
          "Togo", "Cameroun", "Burkina Faso")

Ecrivez un code permettant de créer un vecteur contenant le nombre de caractères de chaque nom de pays. La fonction nchar() permet de compter le nombre de caractères dans une chaîne de caractères.

N.B : La fonction nchar() compte aussi les espaces présents dans une chaîne de caractère

# Correction

lapply(pays, nchar)
## [[1]]
## [1] 5
## 
## [[2]]
## [1] 13
## 
## [[3]]
## [1] 5
## 
## [[4]]
## [1] 4
## 
## [[5]]
## [1] 8
## 
## [[6]]
## [1] 12

La fonction lapply() renvoie toujours une liste quelque soit la structure de données en entrée. Pour obtenir le résultat sous forme de vecteur, vous pouvez écrire :

unlist(lapply(pays, nchar))
## [1]  5 13  5  4  8 12

Il existe un moyen plus simple de traiter le cas où tous les résultats de lapply() ont le même type : utilisation de la fonction sapply().

Reprenons l’exercice d’application précédent en utilisant cette fois-ci sapply() :

# Utilisation de sapply

sapply(pays, nchar)
##         Bénin Côte d'Ivoire         Ghana          Togo      Cameroun 
##             5            13             5             4             8 
##  Burkina Faso 
##            12

Fantastique ! Le résultat de sapply est un vecteur contenant les mêmes information que celles obtenues avec lapply. Cependant, sapply a un affichage plus explicite que lapply car les noms des pays sont présentés.

La fonction vapply() est assez similaire à sapply(). Elle fait appel à lapply et simplifie le résultat. Mais, lorsque vous utilisez vapply, vous devez toujours spécifier le type de valeur retournée.

Considérons l’exemple ci-dessous :

vapply(pays, nchar)

Error in vapply(pays, nchar) : l’argument “FUN.VALUE” est manquant, avec aucune valeur par défaut

Lorsqu’on ne précise pas le type de la valeur retournée par vapply, la fonction retourne un message d’erreur. Pour préciser le type de la valeur retournée, utilisez l’argument FUN.VALUE* :

vapply(pays, nchar, FUN.VALUE = numeric(1))
##         Bénin Côte d'Ivoire         Ghana          Togo      Cameroun 
##             5            13             5             4             8 
##  Burkina Faso 
##            12

7 Chapitre 4 : Importation des données provenant de différentes sources.

Avant d’analyser vos données, vous devez nécessairement les importer préalablement. Dans ce chapitre, vous apprendrez à importer des données provenant de fichiers textes comme .txt, .csv, de fichiers excels (.xlsx), et des données provenant du web.

7.1 Importation des fichiers Excel

Les tableurs en général et Excel en particulier sont des outils très utilisés en analyse des données. R dispose de fonctions permettant d’importer des fichiers excel.

Avant de procéder à l’importation, assurez-vous d’abord que votre fichier R et votre fichier de données soient dans le même dossier dans votre ordinateur. De plus, vous devez définir ce dossier comme étant votre répertoire de travail.

# Obtention du répertoire courant 

getwd()

Pour définir votre répertoire, vous pouvez utiliser la fonction getwd(). Par exemple, pour définir un dossier nommé “None” se trouvant dans le disque D, exécutez le code ci-dessous :

# Exemple de définition de répertoire de travail

setwd("D:/None")

Pour importer les fichiers excel dans R, il faut préalablement importer la librairie readxl.

# Importation de la librairie readxl

library(readxl)

La fonction read_excel() permet d’importer les fichiers excel dans R.

# Arguments de la fonction read_excel()

args(read_excel)
## function (path, sheet = NULL, range = NULL, col_names = TRUE, 
##     col_types = NULL, na = "", trim_ws = TRUE, skip = 0, n_max = Inf, 
##     guess_max = min(1000, n_max), progress = readxl_progress(), 
##     .name_repair = "unique") 
## NULL

path est l’argument indispensable de la fonction read_excel() pour l’importation de fichiers Excel. Il prend pour valeur le chemin d’un fichier d’extension xls ou xlsx. Si votre fichier est dans le même dossier que votre fichier R, vous pouvez dans ce cas spécifier uniquement le nom du fichier sans oublier l’extension comme dans l’exemple ci-dessous où nous importons le fichier excel airbnb_room_type.xlsx :

# Importation d'un fichier excel

airbnb <- read_excel('airbnb_room_type.xlsx')
## Error: `path` does not exist: 'airbnb_room_type.xlsx'
# Type de l'objet airbnb

class(airbnb)
## Error in eval(expr, envir, enclos): objet 'airbnb' introuvable

L’objet airbnb est une dataframe.

# Affichage des cinq premières lignes de la dataframe airbnb

head(airbnb)
## Error in head(airbnb): objet 'airbnb' introuvable

Par défaut, la fonction read_excel() lit la première feuille du fichier excel. Pour lire une autre feuille, vous devez spécifier l’argument sheet. Le fichier datasets.xlsx comporte deux feuilles : IrisSample est la première feuille et mtcars la deuxième feuille. Pour lire la deuxième feuille :

# Importation de la deuxième feuille d'un fichier excel

cars <- read_excel('datasets.xlsx', sheet = 2)
## Error: `path` does not exist: 'datasets.xlsx'
# Affichage des cinq premières lignes de la dataframe cars

head(cars)
##   speed dist
## 1     4    2
## 2     4   10
## 3     7    4
## 4     7   22
## 5     8   16
## 6     9   10

Au lieu de sheet = 2, vous pouvez aussi mettre sheet = ‘mtcars’ :

head(read_excel('datasets.xlsx', sheet = 'mtcars'))
## Error: `path` does not exist: 'datasets.xlsx'

Rappelez-vous que pour obtenir la documentation sur n’importe qu’elle fonction de R, vous pouvez utiliser la fonction help() :

help(read_excel)

7.2 Importation des fichiers plats

Les fichiers plats sont très utilisés en Data Science. Parmi ces fichiers, on a les fichiers csv (Comma Separated Value), txt, tsv, etc.

L’image ci-dessus montre un exemple de fichier CSV. Les informations sont séparées par des virgules. Il s’agit du célèbre jeu de données titanic. Pour importer les fichiers CSV, vous pouvez utiliser la fonction read.csv() :

# Documentation sur la fonction read.csv()

help(read.csv)
# Arguments de la fonction read.csv()

args(read.csv)
## function (file, header = TRUE, sep = ",", quote = "\"", dec = ".", 
##     fill = TRUE, comment.char = "", ...) 
## NULL

Le seul argument de la fonction read.csv() que vous devez absolument spécifié est : file. Cet argument indique le chemin de votre fichier.

# Importation du fichier 'titanic.csv'

tit <- read.csv(file = 'titanic.csv') # read.csv('titanic.csv')
## Warning in file(file, "rt"): impossible d'ouvrir le fichier 'titanic.csv' : No
## such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
# Affichage des cinq premières lignes de la dataframe 

head(tit)
## Error in head(tit): objet 'tit' introuvable

Un cas souvent rencontré est le fait de disposer d’une adresse url de vos données.

# Importaion d'un fichier csv à partir d'une url

titanic_url <- 'https://raw.githubusercontent.com/JosueAfouda/TUTORIALS/main/titanic.csv'

titanic_df <- read.csv(titanic_url)

# Affichage de la dataframe

head(titanic_df)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket    Fare Cabin Embarked
## 1        A/5 21171  7.2500              S
## 2         PC 17599 71.2833   C85        C
## 3 STON/O2. 3101282  7.9250              S
## 4           113803 53.1000  C123        S
## 5           373450  8.0500              S
## 6           330877  8.4583              Q

Un autre cas que vous pouvez aussi rencontré est le fait que le fichier de données n’a pas d’en-têtes c’est-à-dire pas de noms de variables.

# Importation du fichier 'iris.data'

iris_df <- read.csv('iris.data')
## Warning in file(file, "rt"): impossible d'ouvrir le fichier 'iris.data' : No
## such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
# Affichage de la dataframe

head(iris_df)
## Error in head(iris_df): objet 'iris_df' introuvable

La fonction read.csv considère par défaut la première ligne du fichier comme la ligne d’en-têtes. Etant donné que le fichier ‘iris.data’ ne contient pas d’en-têtes, remarquez que la première observation a été définie comme noms de variabes. Pour régler ce genre de problème, vous devez spécifier l’argument header et lui donner la valeur FALSE :

# Importation du fichier 'iris.data'

iris_df <- read.csv('iris.data', header = FALSE)
## Warning in file(file, "rt"): impossible d'ouvrir le fichier 'iris.data' : No
## such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
# Affichage de la dataframe

head(iris_df)
## Error in head(iris_df): objet 'iris_df' introuvable

En mettant header = FALSE , vous dites à R que ce fichier ne contient pas d’en-têtes. Ainsi R attribue un nom à chaque colonne.

Supposons que vous connaissez les noms de variables. Voici comment vous pouvez spécifier ces noms dans votre importation en utilisant l’argument col.names :

# (Re)Importation du fichier 'iris.data'

iris_names <- c('sepal_length', 'sepal_width', 
                'petal_length', 'petal_width' ,
                'class')

iris_df <- read.csv('iris.data', header = FALSE, 
                    col.names = iris_names)
## Warning in file(file, "rt"): impossible d'ouvrir le fichier 'iris.data' : No
## such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
# Affichage de la dataframe

head(iris_df)
## Error in head(iris_df): objet 'iris_df' introuvable

Dans certains cas, vous devez spécifier le délimiteur utilisé dans votre fichier texte (souvent avec les formats .txt). Pour ce faire, utilisez l’argument sep :

# Importons le fichier fishcatch.dat.txt

poissons_url <- 'http://jse.amstat.org/datasets/fishcatch.dat.txt'

poissons <- read.csv(poissons_url)

# Affichage de la dataframe

head(poissons)
##      X1......1.....242.0.....23.2....25.4....30.0....38.4...13.4...NA
## 1     2      1     290.0     24.0    26.3    31.2    40.0   13.8   NA
## 2     3      1     340.0     23.9    26.5    31.1    39.8   15.1   NA
## 3     4      1     363.0     26.3    29.0    33.5    38.0   13.3   NA
## 4     5      1     430.0     26.5    29.0    34.0    36.6   15.1   NA
## 5     6      1     450.0     26.8    29.7    34.7    39.2   14.2   NA
## 6     7      1     500.0     26.8    29.7    34.5    41.1   15.3   NA

Comme vous le constatez, les données ne sont pas bien importées. En effet, dans ce fichier le séparateur n’est pas la virgule mais plutôt un espace.

# (Re)Importons le fichier fishcatch.dat.txt

poissons = read.csv(poissons_url, sep = '')

# Affichage de la dataframe

head(poissons)
##   X1 X1.1 X242.0 X23.2 X25.4 X30.0 X38.4 X13.4 NA.
## 1  2    1    290  24.0  26.3  31.2  40.0  13.8  NA
## 2  3    1    340  23.9  26.5  31.1  39.8  15.1  NA
## 3  4    1    363  26.3  29.0  33.5  38.0  13.3  NA
## 4  5    1    430  26.5  29.0  34.0  36.6  15.1  NA
## 5  6    1    450  26.8  29.7  34.7  39.2  14.2  NA
## 6  7    1    500  26.8  29.7  34.5  41.1  15.3  NA

Supposons que vous connaissez les noms de colonnes :

# (Re)Importons le fichier fishcatch.dat.txt

columns <- c('Species', 'Weight', 'Length1', 
             'Length2', 'Length3', 'Height%', 
             'Width%', 'Sex')


poissons <- read.csv(poissons_url, sep = '', 
                     col.names = columns)

head(poissons)
##   Species Weight Length1 Length2 Length3 Height. Width. Sex
## 2       1    290    24.0    26.3    31.2    40.0   13.8  NA
## 3       1    340    23.9    26.5    31.1    39.8   15.1  NA
## 4       1    363    26.3    29.0    33.5    38.0   13.3  NA
## 5       1    430    26.5    29.0    34.0    36.6   15.1  NA
## 6       1    450    26.8    29.7    34.7    39.2   14.2  NA
## 7       1    500    26.8    29.7    34.5    41.1   15.3  NA

Il y a d’autres cas possibles pouvant être rencontrés lors de l’importation de fichiers plats. N’hésitez pas à toujours regarder la documentation à utiliser l’aide avec la fonction help().

7.3 Importation des données provenant du web

Une importante partie des données utilisées par les Data Scientists se trouvent sur internet. Dans ce chapitre, vous apprendrez à récupérer les données du web à partir de plusieurs sources telles que les API (Application Programming Interface) et aussi le WebScraping.

7.3.1 API

La plupart des grands sites web rendent leurs données disponibles aux utilisateurs à travers les interface de programmation d’applications (API en anglais). Dans 90% des cas, si vous cherchez à obtenir des données provenant du web à partir d’une API, R a probablement un client pour cela c’est-à-dire un package R qui contient des fonctions pour récupérer ces données. les clients API ne sont que des packages R et sont très faciles à utiliser pour réccupérer des données du web. Il vous suffit juste de chercher la documentation relative à chaque API. L’image ci-dessous présente le schéma de fonctionnement d’une API :

Pour illustrer le fonctionnement des API, nous allons importer directement des données de Yahoo Finance en utilisant le package quantmod qui joue le rôle de client pour interagir avec l’API de Yahoo Finance. La librairie quantmod est un package qui a été construit pour assister les trader et les analystes quantitatifs dans le développement, le test et le déployement de modèles statistiques de trading. Commençons par importer cette librairie :

# Installation de la librairie quantmod

# install.packages('quantmod')

# Importation de la librairie

library(quantmod)

Pour récupérer les données de Yahoo Finance, nous utiliserons la fonction getSymbols() du package quantmod.

# Aide sur la fonction getSymbols()

help(getSymbols)

Supposez que vous faites une étude sur la société Apple et que vous avez besoin de ses données boursières. Vous avez juste besoin du symbole en bourse d’APPle c’est-à-dire AAPL :

# Importation des données boursières d'Apple. 

getSymbols(Symbols = "AAPL", src = "yahoo")  # getSymbols("AAPL")
## [1] "AAPL"

Le code getSymbols(Symbols = "AAPL", src = "yahoo") est équivalent au code getSymbols("AAPL"). En effet la source (argument src) par défaut est Yahoo Finance.

Par défaut, l’argument auto.assign est égal à TRUE ce qui signifie que les données sont chargées directement dans l’espace de travail.

# Affichage des premières observations

head(AAPL)
##            AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
## 2007-01-03  3.081786  3.092143 2.925000   2.992857  1238319600      2.547276
## 2007-01-04  3.001786  3.069643 2.993571   3.059286   847260400      2.603815
## 2007-01-05  3.063214  3.078571 3.014286   3.037500   834741600      2.585272
## 2007-01-08  3.070000  3.090357 3.045714   3.052500   797106800      2.598039
## 2007-01-09  3.087500  3.320714 3.041071   3.306071  3349298400      2.813857
## 2007-01-10  3.383929  3.492857 3.337500   3.464286  2952880000      2.948518
# Affichage des dernières observations

tail(AAPL)
##            AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
## 2023-04-05    164.74    165.05   161.80     163.76    51511700        163.76
## 2023-04-06    162.43    164.96   162.00     164.66    45390100        164.66
## 2023-04-10    161.42    162.03   160.08     162.03    47716900        162.03
## 2023-04-11    162.35    162.36   160.51     160.80    47644200        160.80
## 2023-04-12    161.22    162.06   159.78     160.10    50133100        160.10
## 2023-04-13    161.63    165.80   161.42     165.56    68367400        165.56

Vous constatez que les données sont journalières et partent du premier jour d’introduction en bourse de la société à la date de la dernière observation disponible.

Lorsque vous spécifiez auto.assign = FALSE, ceci permet de ne pas charger directement les données dans votre espace de travail. Ainsi vous avez la possibilité de stocker vous-mêmes les données dans une variable.

# Autre façon d'utiliser la fonction getSymbols

apple_df <- getSymbols("AAPL", auto.assign = FALSE)

# Affichage des premières observations

print(head(apple_df, 3))
##            AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
## 2007-01-03  3.081786  3.092143 2.925000   2.992857  1238319600      2.547276
## 2007-01-04  3.001786  3.069643 2.993571   3.059286   847260400      2.603815
## 2007-01-05  3.063214  3.078571 3.014286   3.037500   834741600      2.585272
# Affichage des dernières observations

print(tail(apple_df, 3))
##            AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
## 2023-04-11    162.35    162.36   160.51     160.80    47644200        160.80
## 2023-04-12    161.22    162.06   159.78     160.10    50133100        160.10
## 2023-04-13    161.63    165.80   161.42     165.56    68367400        165.56

Il est possible d’importer les données sur une période précise en utilisant les arguments from et to :

# Importation des données de TESLA sur une période précise

getSymbols("TSLA", from = as.Date("2015-01-01"), 
           to = as.Date("2020-01-01"))
## [1] "TSLA"
# Affichage des premières observations

print(head(TSLA, 3))
##            TSLA.Open TSLA.High TSLA.Low TSLA.Close TSLA.Volume TSLA.Adjusted
## 2015-01-02  14.85800  14.88333 14.21733   14.62067    71466000      14.62067
## 2015-01-05  14.30333  14.43333 13.81067   14.00600    80527500      14.00600
## 2015-01-06  14.00400  14.28000 13.61400   14.08533    93928500      14.08533
# Affichage des dernières observations

print(tail(TSLA, 3))
##            TSLA.Open TSLA.High TSLA.Low TSLA.Close TSLA.Volume TSLA.Adjusted
## 2019-12-27    29.000  29.02067 28.40733   28.69200   149185500      28.69200
## 2019-12-30    28.586  28.60000 27.28400   27.64667   188796000      27.64667
## 2019-12-31    27.000  28.08600 26.80533   27.88867   154285500      27.88867

La fonction getSymbols() permet aussi d’importer les données de plusieurs titres sur une seule requête :

# Création d'un environnement de stockage des données

stocks <- new.env()

# Vecteur des titres (symboles) financiers

stocks_names <- c("GOOG", "AMZN", "AAPL", "MSFT", "IBM")

# Importation des données de plusieurs titres

getSymbols(stocks_names, env = stocks)
## [1] "GOOG" "AMZN" "AAPL" "MSFT" "IBM"
# Google

head(stocks$GOOG, 3)
##            GOOG.Open GOOG.High GOOG.Low GOOG.Close GOOG.Volume GOOG.Adjusted
## 2007-01-03  11.60650  11.87200 11.48470   11.64610   309415434      11.64610
## 2007-01-04  11.68122  12.05357 11.66503   12.03638   316686586      12.03638
## 2007-01-05  12.01746  12.14199 11.90812   12.13427   275914333      12.13427
# Amazon

head(stocks$AMZN, 3)
##            AMZN.Open AMZN.High AMZN.Low AMZN.Close AMZN.Volume AMZN.Adjusted
## 2007-01-03    1.9340    1.9530   1.9025     1.9350   248102000        1.9350
## 2007-01-04    1.9295    1.9570   1.9130     1.9450   126368000        1.9450
## 2007-01-05    1.9360    1.9395   1.8800     1.9185   132394000        1.9185
# Apple

head(stocks$AAPL, 3)
##            AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
## 2007-01-03  3.081786  3.092143 2.925000   2.992857  1238319600      2.547276
## 2007-01-04  3.001786  3.069643 2.993571   3.059286   847260400      2.603815
## 2007-01-05  3.063214  3.078571 3.014286   3.037500   834741600      2.585272

Pour récupérer par exemple les prix de clôtures de chaque actif et les avoir dans une seule dataframe :

# Extraire les prix de clôture de chaque titre pour en former un seul ensemble de données xts

close_prices <- do.call(merge, lapply(stocks, Cl))

# Affichage des premières observations

head(close_prices)
##            AAPL.Close IBM.Close GOOG.Close AMZN.Close MSFT.Close
## 2007-01-03   2.992857  92.99236   11.64610     1.9350      29.86
## 2007-01-04   3.059286  93.98662   12.03638     1.9450      29.81
## 2007-01-05   3.037500  93.13576   12.13427     1.9185      29.64
## 2007-01-08   3.052500  94.55067   12.04435     1.8750      29.93
## 2007-01-09   3.306071  95.66921   12.09218     1.8890      29.96
## 2007-01-10   3.464286  94.54111   12.19081     1.8575      29.66

7.3.2 Web Scraping

Dans la section précédente, nous avons vu un cas pratique d’utilisation d’une API pour récupérer les données sur un site web. Le problème est que certains sites web ne disposent pas d’une API ou d’autres dispositifs pouvant faciliter la récupération de leurs données. Dans de tels cas, vous pouvez recourir au Web Scraping. Selon Wikipédia : «Le web scraping est une technique d’extraction du contenu d’un site Web, via un script ou un programme, dans le but de le transformer pour permettre son utilisation dans un autre contexte, par exemple le référencement». Dans cette section, à travers deux cas pratiques (récupération de tableaux de données sur un site web et récupération de données sur un site de location), vous apprendrez des techniques de web scraping.

7.3.2.1 Cas pratique n°1 : Récupération des données d’un site web de location d’appartements

Vous êtes Data Scientist dans une société d’investissement immobilier et vous êtes chargés de faire une étude de marché sur les locations d’appartement dans la ville de Rennes (France). Pour bien mener cette étude, vous devez collecter les données d’un site web d’une agence immobilière. Malheureusement, cette agence ne dispose pas d’une API pour vous permettre de récupérer facilement leurs données. De ce fait, vous êtes obligé de recourir au web scraping.

La première étape de ce processus consiste à importer les librairies nécessaires c’est-à-dire les packages rvest et stringr :

# Importation des librairies

library(rvest)

library(stringr)

rvest est un package de R permettant d’effectuer toutes les tâches de web scraping dans le but d’extraire facilement les données du web. stringr a été conçu pour la manipulation des chaînes de caractères et dans le cadre de la préparation et du nettoyage des données.

Après avoir récupéré le lien de la page web, vous utiliserez la fonction read_html() du package rvest pour en lire le contenu :

# Adresse de la page web

lien = "https://www.ouestfrance-immo.com/immobilier/vente/appartement-1-piece/rennes-35-35238/"

# Lecture du contenu du site web

contenu_html <- read_html(lien)

contenu_html
## {html_document}
## <html class="no-js" lang="fr-FR">
## [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8 ...
## [2] <body class="banniereHautHidden  fullListe keyboardless liste vente" data ...

Comme vous le voyez ci-dessus, la fonction read_html() retourne le code HTML de la page web. Une autre manière de lire le code HTML d’une page web est de faire un clic droit sur cette page puis de cliquer sur Inspecter. L’image ci-dessous montre le code HTML du site web de l’agence immobilière :

L’objectif est de récupérer les prix (en €) et les surfaces (en m²) des logements et de les mettre dans une dataframe. Soulignons que les éléments d’une page web sont organisés en noeuds (nodes). Dans le cas présent, en explorant le code HTML, nous avons constaté que les prix sont stockés dans les noeuds .annPrix et les surfaces sont stockées dans les noeuds .annCriteres. Pour récupérer un noeud du document contenu_html, vous devez utiliser la fonction html_nodes() du package rvest :

# Récupération des données du noeud ".annCriteres"

castCritere <- contenu_html %>% html_nodes(".annCriteres")

castCritere
## {xml_nodeset (25)}
##  [1] <span class="annCriteres">\n                        <div>20<span class=" ...
##  [2] <span class="annCriteres">\n                        <div>37<span class=" ...
##  [3] <span class="annCriteres">\n                        <div>22<span class=" ...
##  [4] <span class="annCriteres">\n                        <div>28<span class=" ...
##  [5] <span class="annCriteres">\n                        <div>20<span class=" ...
##  [6] <span class="annCriteres">\n                        <div>23<span class=" ...
##  [7] <span class="annCriteres">\n                        <div>30<span class=" ...
##  [8] <span class="annCriteres">\n                        <div>29<span class=" ...
##  [9] <span class="annCriteres">\n                        <div>18<span class=" ...
## [10] <span class="annCriteres">\n                        <div>17<span class=" ...
## [11] <span class="annCriteres">\n                        <div>33<span class=" ...
## [12] <span class="annCriteres">\n                        <div>36<span class=" ...
## [13] <span class="annCriteres">\n                        <div>27<span class=" ...
## [14] <span class="annCriteres">\n                        <div>23<span class=" ...
## [15] <span class="annCriteres">\n                        <div>35<span class=" ...
## [16] <span class="annCriteres">\n                        <div>21<span class=" ...
## [17] <span class="annCriteres">\n                        <div>19<span class=" ...
## [18] <span class="annCriteres">\n                        <div>30<span class=" ...
## [19] <span class="annCriteres">\n                        <div>28<span class=" ...
## [20] <span class="annCriteres">\n                        <div>34<span class=" ...
## ...
# Transformation des données en dataframe

df_Cri <- as.data.frame(html_text(castCritere))

df_Cri
##                                               html_text(castCritere)
## 1             \n                        20m²Terr                    
## 2       \n                        37m²1 chb1 sdb                    
## 3        \n                        22m²1 sdbElec                    
## 4       \n                        28m²2ème étage                    
## 5       \n                        20m²1 chb1 sdb                    
## 6  \n                        23m²1 sdb3ème étage                    
## 7  \n                        30m²1 sdb4ème étage                    
## 8         \n                        29m²1 sdbPkg                    
## 9        \n                        18m²1 sdbElec                    
## 10        \n                        17m²1 sdbEst                    
## 11      \n                        33m²1 chb1 sdb                    
## 12        \n                        36m²1 sdbGaz                    
## 13        \n                        27m²1 sdbPkg                    
## 14       \n                        23m²1 sdbElec                    
## 15        \n                        35m²1 sdbGaz                    
## 16                \n                        21m²                    
## 17                \n                        19m²                    
## 18       \n                        30m²1 sdbElec                    
## 19        \n                        28m²1 sdbAsc                    
## 20        \n                        34m²1 sdbAsc                    
## 21        \n                        35m²1 sdbAsc                    
## 22        \n                        32m²1 sdbAsc                    
## 23        \n                        35m²1 sdbAsc                    
## 24        \n                        32m²1 sdbAsc                    
## 25        \n                        35m²1 sdbAsc

Nous allons maintenant procéder à un changement de nom de la colonne et à une extraction des chiffres représentant les superficies des logements :

names(df_Cri) <- "Superficie"

df_Cri <- as.data.frame(stringr::str_extract(df_Cri$Superficie, "\\d+"))

names(df_Cri) <- "Superficie"

df_Cri
##    Superficie
## 1          20
## 2          37
## 3          22
## 4          28
## 5          20
## 6          23
## 7          30
## 8          29
## 9          18
## 10         17
## 11         33
## 12         36
## 13         27
## 14         23
## 15         35
## 16         21
## 17         19
## 18         30
## 19         28
## 20         34
## 21         35
## 22         32
## 23         35
## 24         32
## 25         35

Faisons les mêmes opérations pour récupérer les données du noeud .annPrix :

castPrix <- contenu_html %>% html_nodes(".annPrix")

df_prix <- as.data.frame(html_text(castPrix))

names(df_prix) <- "Prix"

df_prix <- as.data.frame(stringr::str_extract(df_prix$Prix, "\\d+"))

names(df_prix) <- "Prix"

df_prix
##    Prix
## 1   157
## 2   194
## 3   100
## 4    25
## 5   119
## 6    77
## 7   161
## 8   209
## 9   128
## 10   99
## 11  192
## 12  197
## 13  132
## 14  114
## 15  290
## 16  157
## 17  152
## 18  172
## 19  180
## 20  255
## 21  300
## 22  290
## 23  275
## 24  275
## 25  280
# Jointure des deux dataframes

df_annonce<-cbind(df_Cri,df_prix)

df_annonce
##    Superficie Prix
## 1          20  157
## 2          37  194
## 3          22  100
## 4          28   25
## 5          20  119
## 6          23   77
## 7          30  161
## 8          29  209
## 9          18  128
## 10         17   99
## 11         33  192
## 12         36  197
## 13         27  132
## 14         23  114
## 15         35  290
## 16         21  157
## 17         19  152
## 18         30  172
## 19         28  180
## 20         34  255
## 21         35  300
## 22         32  290
## 23         35  275
## 24         32  275
## 25         35  280
# Structure de la dataframe

str(df_annonce)
## 'data.frame':    25 obs. of  2 variables:
##  $ Superficie: chr  "20" "37" "22" "28" ...
##  $ Prix      : chr  "157" "194" "100" "25" ...

Les données sont sous forme de chaînes de caractères donc il ne sera pas possible de calculer des statistiques descriptives. Pour remédier à ce problème, vous devez transformer le type des variables :

# Transformation en variables numériques

df_annonce$Superficie <- as.numeric(df_annonce$Superficie)

df_annonce$Prix <- as.numeric(df_annonce$Prix)

# Vérification de la nouvelle structure des données

str(df_annonce)
## 'data.frame':    25 obs. of  2 variables:
##  $ Superficie: num  20 37 22 28 20 23 30 29 18 17 ...
##  $ Prix      : num  157 194 100 25 119 77 161 209 128 99 ...

Tout le processus précédent a permis de récupérer uniquement les données de la première page. Pour récupérer les données des 10 pages suivantes, vous pouvez utiliser une boucle for (Confère Chapitre 2).

Soulignons que lorsque vous cliquez sur la deuxième page, voici le lien qui s’affiche dans la barre d’adresse de votre navigateur : “https://www.ouestfrance-immo.com/immobilier/vente/appartement-1-piece/rennes-35-35238/”,“?page=2”.

Le code ci-dessous présente le résultat que vous devez obtenir :

# Boucle for pour les 10 autres pages

n_pages = 10 

# Création d'une dataframe vide devant accueillir toutes les données

df = data.frame()

for (i in 2:n_pages) {
  Lien = paste(
    "https://www.ouestfrance-immo.com/immobilier/vente/appartement-1-piece/rennes-35-35238/","?page=",
    i, 
    sep=""
    )
  
  
  # acceder au contenu du site 
    # (même script pour obtenir les données de la première page)
  
  Contenu_html <- read_html(Lien)
  
  CastCritere <- Contenu_html %>% html_nodes(".annCriteres")
  
  Df_Cri<-as.data.frame(html_text(CastCritere))
  
  names(Df_Cri) <- "Superficie"
  
  Df_Cri<-as.data.frame(stringr::str_extract(Df_Cri$Superficie, "\\d+"))
  
  names(Df_Cri) <- "Superficie"
  
  
  CastPrix <- Contenu_html %>% html_nodes(".annPrix")
  
  Df_prix <- as.data.frame(html_text(CastPrix))
  
  names(Df_prix) <- "Prix"
  
  Df_annonce <- cbind(Df_Cri,Df_prix)
  
  # Dataframe des données des 10 pages suivantes
  
  df <- rbind(df, Df_annonce)
}

# La dataframe totale est la fusion de la dataframe df_annone (1ère page) 
  # et de la dataframe df(les 10 pages suivantes) 

df_total <- rbind(df_annonce, df)

head(df_total)
##   Superficie Prix
## 1         20  157
## 2         37  194
## 3         22  100
## 4         28   25
## 5         20  119
## 6         23   77
# Transformation en variables numériques

df_total$Superficie <- as.numeric(df_total$Superficie)

df_total$Prix <- as.numeric(df_total$Prix)

# Vérification de la nouvelle structure des données

str(df_total)
## 'data.frame':    250 obs. of  2 variables:
##  $ Superficie: num  20 37 22 28 20 23 30 29 18 17 ...
##  $ Prix      : num  157 194 100 25 119 77 161 209 128 99 ...

7.3.2.2 Cas pratique n°2 : Récupération des tableaux d’une page web

Il existe des cas où les pages web contiennent directement des tables de données.

Vous faites une étude sur le S&P500 qui comprend les 500 plus grandes sociétés américaines en termes de capitalisation boursière et couvre environ 80% du secteur boursier américain. En effet, cet indice est très souvent utilisé comme représentant de l’ensemble du marché boursier américain. Vous avez trouvez sur Wikipédia un tableau donnant la liste de toutes les entreprises du S&P500 et vous voulez importez ce tableau dans R. Pour ce faire, vous pouvez utiliser la fonction html_table() du package rvest :

# Lecture de la page web

sp500_html <- read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies")

# Importation d'ue table provenant d'une page web

sp500_societes <- html_table(sp500_html, fill = TRUE)

print(class(sp500_societes))
## [1] "list"

Le résultat est une liste contenant tous les tableaux présents sur la page web. Pour récupérer par exemple le deuxième tableau de la page :

# Récupération du deuxième tableau

sp500_stocks <- sp500_societes[[1]]

print(head(sp500_stocks))
## # A tibble: 6 × 8
##   Symbol Security            GICS Secto…¹ GICS …² Headq…³ Date …⁴    CIK Founded
##   <chr>  <chr>               <chr>        <chr>   <chr>   <chr>    <int> <chr>  
## 1 MMM    3M                  Industrials  Indust… Saint … 1957-0… 6.67e4 1902   
## 2 AOS    A. O. Smith         Industrials  Buildi… Milwau… 2017-0… 9.11e4 1916   
## 3 ABT    Abbott              Health Care  Health… North … 1957-0… 1.8 e3 1888   
## 4 ABBV   AbbVie              Health Care  Pharma… North … 2012-1… 1.55e6 2013 (…
## 5 ACN    Accenture           Information… IT Con… Dublin… 2011-0… 1.47e6 1989   
## 6 ATVI   Activision Blizzard Communicati… Intera… Santa … 2015-0… 7.19e5 2008   
## # … with abbreviated variable names ¹​`GICS Sector`, ²​`GICS Sub-Industry`,
## #   ³​`Headquarters Location`, ⁴​`Date added`
print(class(sp500_stocks))
## [1] "tbl_df"     "tbl"        "data.frame"

Le résultat est effectivement une dataframe que vous pouvez utiliser dans vos analyses.

Cette formation est la suite logique des cours Apprendre à coder avec le langage R dans RStudio (Partie 1 Débutant absolu) et Apprendre à coder avec le langage R dans RStudio (Partie 2 Niveau Intermédiaire). Nous ne reviendrons donc pas sur ces prérecquis. Si vous êtes un débutant en programmation avec R, je vous conseille de suivre d’abord ces deux premières parties avant d’aborder celle-ci.

Dans cette troisième et dernière partie de la la formation sur la programmation avec le langage R, vous apprendrez entres autres à :

  • manipuler les données à la manière Tidyverse avec les fonctions filter(), arrange(), mutate(), select(), summarise() et group_by() ;

  • créer des graphiques tels que les nuages de points (avec droite de régression), les diagrammes à barres, les courbes, les histogrammes, les boîtes à moustache ainsi que des subplots (sous-graphiques) pour visualiser vos données ;

  • traiter les variables catégorielles en utilisant les fonctionnalités de la librairie forcats ;

  • effectuer des jointures de tables (jointure interne, à gauche, à droite, complète ainsi qu’une semi-jointure et une anti-jointure) avec la librairie dplyr ;

  • Etc.

8 Chapitre 5 : Introduction à la librairie Tidyverse

Tidyverse est une collection de packages R open source créée pour la Data Science. Les packages qui composent Tidyverse suivent la même philosophie et la même structure. Au nombre d’entre eux, on peut citer : ggplot2, dplyr, tidyr, etc.

L’installation de tidyverse (install.packages("tidyverse) permet donc d’installer automatiquement les différents packages qui le composent. Dans ce chapitre, vous apprendrez :

  • nettoyer les données ;

  • visualiser les données ;

  • agréger les données et calculer des statistiques descriptives ;

  • manipuler des variables catégorielles.

8.1 Traitement des données

Commençons d’abord par importer la librairie tidyverse :

# Importation de la librairie tidyverse

library(tidyverse)

Pour illustrer les différents concepts de transformation et nettoyage des données, nous utiliserons le célèbre jeu de données gapminder. Il s’agit des données sur des indicateurs socio-économiques comme l’espérance de vie et le PIB (Produit Intérieur Brut) au cours du temps et dans presque tous les pays du monde. Avant d’importer cet ensemble de données, vous devez préalablement importer la librairie gapminder

# Importation de la librairie gapminder

library(gapminder)

# Affichage des premières lignes

head(gapminder)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.
# Structure de la dataframe

str(gapminder)
## tibble [1,704 × 6] (S3: tbl_df/tbl/data.frame)
##  $ country  : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ year     : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
##  $ lifeExp  : num [1:1704] 28.8 30.3 32 34 36.1 ...
##  $ pop      : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
##  $ gdpPercap: num [1:1704] 779 821 853 836 740 ...

L’ensemble de données gapminder contient 1704 observations (lignes) et 6 variables (colonnes). Les variables sont :

  • country : pays ;

  • continent : continent (exemple : Afrique) ;

  • year : année ;

  • lifeExp : espérance de vie ;

  • pop : effectif de la population ;

  • gdpPercap : PIB par habitant.

Il est très important de comprendre la signification des observations dans une dataframe. Ici, par exemple, la première observation donne les indicateurs économiques de l’Afghanistan en 1952. Donc chaque ligne de la dataframe représente une paire unique de pays et d’année. Par ailleurs, les variables sont stockées dans un type de données cohérent. L’espérance de vie et le PIB par habitant sont des variables numériques ; L’année et l’effectif de la population sont des nombres entiers ; Les variables indiquant le pays et le continent sont catégorielles (Factor).

8.1.1 Filtration des données

La filtration est l’une des opération très utilisée en analyse de données. Vous filtrez vos données lorsque vous voulez examiner un sous-ensemble en fonction d’une condition particulière. Dans tidyverse, précisément avec le package dplyr, la filtration s’effectue avec la fonction filter().

# Modalités de la variable 'year'

unique(gapminder$year)
##  [1] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 2002 2007

Suposons que vous voulez analyser uniquement les données de 2002. Vous devez alors créer une dataframe composée uniquement des observations de 2002; A la manière de tidyverse, le code s’écrit comme ci-dessous :

# Données de 2002

gapminder_2002 <- gapminder %>%
  
  filter(year == 2002)

head(gapminder_2002)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       2002    42.1 25268405      727.
## 2 Albania     Europe     2002    75.7  3508512     4604.
## 3 Algeria     Africa     2002    71.0 31287142     5288.
## 4 Angola      Africa     2002    41.0 10866106     2773.
## 5 Argentina   Americas   2002    74.3 38331121     8798.
## 6 Australia   Oceania    2002    80.4 19546792    30688.

Le code ci-dessus a permis de filtrer les données de gapminder pour ne garder que les observations où l’année est égale à 2002. Reamrquez l’utilisation du symbole %>%. Il s’agit de l’opérateur pipe du package dplyr.

# Vérification

unique(gapminder_2002$year)
## [1] 2002

gapminder_2002 est bel est bien un sous-ensemble de gapminder contenant uniquement les observations de l’année 2002. Les conditions de filtration peuvent être plus ou moins complexes. Le code ci-dessous permet de créer un sous-ensemble de données composé des observations du continent africain et pour l’année 2007 :

afrique_2007 <- gapminder %>%
  filter(continent == 'Africa' & year == 2007)

head(afrique_2007)
## # A tibble: 6 × 6
##   country      continent  year lifeExp      pop gdpPercap
##   <fct>        <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Algeria      Africa     2007    72.3 33333216     6223.
## 2 Angola       Africa     2007    42.7 12420476     4797.
## 3 Benin        Africa     2007    56.7  8078314     1441.
## 4 Botswana     Africa     2007    50.7  1639131    12570.
## 5 Burkina Faso Africa     2007    52.3 14326203     1217.
## 6 Burundi      Africa     2007    49.6  8390505      430.
str(afrique_2007)
## tibble [52 × 6] (S3: tbl_df/tbl/data.frame)
##  $ country  : Factor w/ 142 levels "Afghanistan",..: 3 4 11 14 17 18 20 22 23 27 ...
##  $ continent: Factor w/ 5 levels "Africa","Americas",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ year     : int [1:52] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
##  $ lifeExp  : num [1:52] 72.3 42.7 56.7 50.7 52.3 ...
##  $ pop      : int [1:52] 33333216 12420476 8078314 1639131 14326203 8390505 17696293 4369038 10238807 710960 ...
##  $ gdpPercap: num [1:52] 6223 4797 1441 12570 1217 ...

Le jeu de données contient bel et bien 52 observations (les 52 états africains) et 6 variables pour l’année 2007.

Outre le filtrage d’un seul continent, on peut filtrer les observations pour plusieurs continents. Par exemple, filtrons les données de telle sorte à avoir les observations de l’Afrique et de l’Asie :

gapminder %>%
  
  filter(continent %in% c("Africa", "Asia")) %>%
  
  head()
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.

8.1.1.1 Exercice d’application

Créez un sous-ensemble de données contenant uniquement les observations des Etats-Unis avec un PIB par habitant supérieur ou égal à 25000 dollars.

# Correction

gapminder_usa <- gapminder %>%
  
  filter(country == "United States" & gdpPercap >= 25000)

gapminder_usa
## # A tibble: 6 × 6
##   country       continent  year lifeExp       pop gdpPercap
##   <fct>         <fct>     <int>   <dbl>     <int>     <dbl>
## 1 United States Americas   1982    74.6 232187835    25010.
## 2 United States Americas   1987    75.0 242803533    29884.
## 3 United States Americas   1992    76.1 256894189    32004.
## 4 United States Americas   1997    76.8 272911760    35767.
## 5 United States Americas   2002    77.3 287675526    39097.
## 6 United States Americas   2007    78.2 301139947    42952.

Ces conditions de filtration ont réduites de moitié les observations en passant de 12 lignes à 6.

8.1.2 Tri des observations

Une autre opération très courante en traitement des données est le tri des observations par ordre croissant ou décroissant selon l’une des variables de la dataframe. Pour trier les données à la manière de tidyverse, vous pouvez utiliser la fonction arrange(). Supposons que vous voulez connaître le pays ainsi que l’année où le PIB par habitant est le plus faible. Pour cela, vous devez trier par ordre croissant les observations selon la variable gdpPercap :

# Tri des données selon l'ordre croissant du PIB par habitant

gapminder %>% 
  
  arrange(gdpPercap) %>% 
  
  head()
## # A tibble: 6 × 6
##   country          continent  year lifeExp      pop gdpPercap
##   <fct>            <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Congo, Dem. Rep. Africa     2002    45.0 55379852      241.
## 2 Congo, Dem. Rep. Africa     2007    46.5 64606759      278.
## 3 Lesotho          Africa     1952    42.1   748747      299.
## 4 Guinea-Bissau    Africa     1952    32.5   580653      300.
## 5 Congo, Dem. Rep. Africa     1997    42.6 47798986      312.
## 6 Eritrea          Africa     1952    35.9  1438760      329.

Le tableau ci-dessus nous montre que c’est le PIB de la République Démocratique du Congo en 2002 qui est le plus faible dans l’ensemble des données gapminder. Donc, par défaut, la fonction arrange() trie les observations par ordre croissant.

Supposons maintenant que vous voulez connaître le pays ainsi que l’année où le PIB par habitant est le plus élevé. Pour cela, vous devez trier par ordre décroissant les observations selon la variable gdpPercap :

# Tri des données selon l'ordre décroissant du PIB par habitant

gapminder %>% 
  
  arrange(desc(gdpPercap)) %>% 
  
  head()
## # A tibble: 6 × 6
##   country continent  year lifeExp     pop gdpPercap
##   <fct>   <fct>     <int>   <dbl>   <int>     <dbl>
## 1 Kuwait  Asia       1957    58.0  212846   113523.
## 2 Kuwait  Asia       1972    67.7  841934   109348.
## 3 Kuwait  Asia       1952    55.6  160000   108382.
## 4 Kuwait  Asia       1962    60.5  358266    95458.
## 5 Kuwait  Asia       1967    64.6  575003    80895.
## 6 Kuwait  Asia       1977    69.3 1140357    59265.

Le tableau ci-dessus nous montre que c’est le PIB du Kowët en 1957 qui était le plus élevé dans l’ensemble de données gapminder. Donc, c’est la fonction desc() qui permet le tri par ordre décroissant.

On peut enchaîner les opérations de filtration et de tri. Le code ci-dessous permet de filtrer les données de telle sorte à obtenir uniquement les observations du Bénin et à les trier par ordre croissant du PIB par habitant :

gapminder %>%
  
  filter(country == "Benin") %>%
  
  arrange(gdpPercap)
## # A tibble: 12 × 6
##    country continent  year lifeExp     pop gdpPercap
##    <fct>   <fct>     <int>   <dbl>   <int>     <dbl>
##  1 Benin   Africa     1962    42.6 2151895      949.
##  2 Benin   Africa     1957    40.4 1925173      960.
##  3 Benin   Africa     1977    49.2 3168267     1029.
##  4 Benin   Africa     1967    44.9 2427334     1036.
##  5 Benin   Africa     1952    38.2 1738315     1063.
##  6 Benin   Africa     1972    47.0 2761407     1086.
##  7 Benin   Africa     1992    53.9 4981671     1191.
##  8 Benin   Africa     1987    52.3 4243788     1226.
##  9 Benin   Africa     1997    54.8 6066080     1233.
## 10 Benin   Africa     1982    50.9 3641603     1278.
## 11 Benin   Africa     2002    54.4 7026113     1373.
## 12 Benin   Africa     2007    56.7 8078314     1441.

8.1.2.1 Exercice d’application

Le code ci-dessous permet de filtrer les données de telle sorte à obtenir les observations où l’effectif de la population est supérieur à 10000000 d’habitants et trier ces observations dans l’ordre décroissant de l’espérance de vie.

# Correction

gapminder %>%
  
  filter(pop > 10000000) %>%
  
  arrange(desc(lifeExp)) %>%
  
  head()
## # A tibble: 6 × 6
##   country   continent  year lifeExp       pop gdpPercap
##   <fct>     <fct>     <int>   <dbl>     <int>     <dbl>
## 1 Japan     Asia       2007    82.6 127467972    31656.
## 2 Japan     Asia       2002    82   127065841    28605.
## 3 Australia Oceania    2007    81.2  20434176    34435.
## 4 Spain     Europe     2007    80.9  40448191    28821.
## 5 Japan     Asia       1997    80.7 125956499    28817.
## 6 France    Europe     2007    80.7  61083916    30470.

8.1.3 Création de nouvelles variables

Il est courant de transformer les variables d’un ensemble de données ou d’en créer de nouvelles. Pour effectuer ce genre d’opérations, vous pouvez utiliser la fonction mutate(). Transformons les valeurs de la variable pop en millier d’habitants :

# Transformation de la population 'pop'

gapminder %>%
  
  mutate(pop = pop / 1000) %>%
  
  head()
## # A tibble: 6 × 6
##   country     continent  year lifeExp    pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>  <dbl>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425.      779.
## 2 Afghanistan Asia       1957    30.3  9241.      821.
## 3 Afghanistan Asia       1962    32.0 10267.      853.
## 4 Afghanistan Asia       1967    34.0 11538.      836.
## 5 Afghanistan Asia       1972    36.1 13079.      740.
## 6 Afghanistan Asia       1977    38.4 14880.      786.

Supposons que vous voulez analyser le PIB total c’est-à-dire le PIB par habitant multiplié par la population. Pour ce faire, vous devez créer une nouvelle variable qui stocke le PIB total :

# Création d'une nouvelle variable

gapminder %>%
  
  mutate(total_gdp = gdpPercap * pop) %>%
  
  head()
## # A tibble: 6 × 7
##   country     continent  year lifeExp      pop gdpPercap    total_gdp
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>        <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.  6567086330.
## 2 Afghanistan Asia       1957    30.3  9240934      821.  7585448670.
## 3 Afghanistan Asia       1962    32.0 10267083      853.  8758855797.
## 4 Afghanistan Asia       1967    34.0 11537966      836.  9648014150.
## 5 Afghanistan Asia       1972    36.1 13079460      740.  9678553274.
## 6 Afghanistan Asia       1977    38.4 14880372      786. 11697659231.

La variable total_gdp a bel et bien été créé. Mais ici le résultat n’a pas éé stocké en mémoire.

8.1.3.1 Exercice d’application

En utilisant successivement les fonctions mutate(), filter(), arrange(), déterminez le pays ayant obtenu le PIB total le plus élevé en 2007.

# Correction

gapminder %>%
  
  filter(year == 2007) %>%
  
  mutate(total_gdp = gdpPercap * pop) %>%
  
  arrange(desc(total_gdp)) %>%
  
  head()
## # A tibble: 6 × 7
##   country        continent  year lifeExp        pop gdpPercap total_gdp
##   <fct>          <fct>     <int>   <dbl>      <int>     <dbl>     <dbl>
## 1 United States  Americas   2007    78.2  301139947    42952.   1.29e13
## 2 China          Asia       2007    73.0 1318683096     4959.   6.54e12
## 3 Japan          Asia       2007    82.6  127467972    31656.   4.04e12
## 4 India          Asia       2007    64.7 1110396331     2452.   2.72e12
## 5 Germany        Europe     2007    79.4   82400996    32170.   2.65e12
## 6 United Kingdom Europe     2007    79.4   60776238    33203.   2.02e12

Prenons par exemple le cas de la Chine pour faire la difference entre le PIB total et le PIB réel. On remarque que la Chine occupe la deuxième place après les Etats-Unis du fait de son PIB total, ce qui n’est pas le cas lorsqu’on considère le PIB par habitant.

8.1.4 Sélection de variables

Il est possible de ne pas vouloir travailler avec toutes les variables d’un ensemble de données. Dans ce cas, vous pouvez utiliser la fonction select() pour sélectionner uniquement les variables qui vous intéressent.

# Création d'une nouvelle dataframe composée uniquement
  # des variables 'country', 'year' et 'lifeExp'

vars <- c('country', 'year', 'lifeExp')

df <- gapminder %>%
  
  select(vars)

head(df)
## # A tibble: 6 × 3
##   country      year lifeExp
##   <fct>       <int>   <dbl>
## 1 Afghanistan  1952    28.8
## 2 Afghanistan  1957    30.3
## 3 Afghanistan  1962    32.0
## 4 Afghanistan  1967    34.0
## 5 Afghanistan  1972    36.1
## 6 Afghanistan  1977    38.4

Supposons que vous voulez créer une dataframe constituée des variables qui ne sont pas dans le vecteur vars défini ci-dessus. Pour ce faire, vous pouvez utiliser l’opérateur ! :

# Dataframe constituée uniquement des variables 
  # 'continent', 'pop' et 'gdpPercap'

df_new <- gapminder %>%
  
  select(!vars) %>%
  
  head()

Il est aussi possible de sélectionner des variables d’un certain type de données en utilisant la fonction select_if() :

# Sélection des variables de type 'integer' (nombres entiers naturels)

gapminder_int <- gapminder %>%
  
  select_if(is.integer)

head(gapminder_int)
## # A tibble: 6 × 2
##    year      pop
##   <int>    <int>
## 1  1952  8425333
## 2  1957  9240934
## 3  1962 10267083
## 4  1967 11537966
## 5  1972 13079460
## 6  1977 14880372

De la même manière, vous pouvez sélectionner uniquement les variables catégorielles avec la fonction is.factor() :

# Sélection des variables de type 'factor' 

gapminder_factor <- gapminder %>%
  
  select_if(is.factor)

head(gapminder_factor)
## # A tibble: 6 × 2
##   country     continent
##   <fct>       <fct>    
## 1 Afghanistan Asia     
## 2 Afghanistan Asia     
## 3 Afghanistan Asia     
## 4 Afghanistan Asia     
## 5 Afghanistan Asia     
## 6 Afghanistan Asia

8.1.4.1 Exercice d’application

Sélectionnez les variables de gapminder de type numérique.

# Correction

gapminder_numeric <- gapminder %>%
  
  select_if(is.numeric)

head(gapminder_numeric)
## # A tibble: 6 × 4
##    year lifeExp      pop gdpPercap
##   <int>   <dbl>    <int>     <dbl>
## 1  1952    28.8  8425333      779.
## 2  1957    30.3  9240934      821.
## 3  1962    32.0 10267083      853.
## 4  1967    34.0 11537966      836.
## 5  1972    36.1 13079460      740.
## 6  1977    38.4 14880372      786.

Les variables numériques sont l’ensemble des variables constituées d’entiers naturels et de décimaux.

8.1.5 Grouper les données et calculer une statistique récapitulative

Supposons que vous voulez calculer l’espérance de vie moyenne pour chaque pays au cours de la période des données de gapminder. Pour réaliser cette tâche, vous devez d’abord sélectionner les variables concernées (‘country’ et ‘lifeExp’), puis les grouper à l’aide de la fonction group_by() par pays et calculer l’espérance de vie moyenne à l’aide de la fonction summarise().

# Exemple de group_by et summarise

gapminder %>%
  
  # Sélection des variables 'country' et 'lifeExp'
  
  select(c('country', 'lifeExp')) %>%
  
  # Groupement des observations selon les pays
  
  group_by(country) %>%
  
  # Calcul de l'espérance de vie moyenne par pays
  
  summarise(lifeExp_mean = mean(lifeExp)) %>%
  
  # Affichage des premières observations
  
  head()
## # A tibble: 6 × 2
##   country     lifeExp_mean
##   <fct>              <dbl>
## 1 Afghanistan         37.5
## 2 Albania             68.4
## 3 Algeria             59.0
## 4 Angola              37.9
## 5 Argentina           69.1
## 6 Australia           74.7

Vous pouvez trier le résultat final :

gapminder %>%
  
  select(c('country', 'lifeExp')) %>%
  
  group_by(country) %>%
  
  summarise(lifeExp_mean = mean(lifeExp)) %>%
  
  arrange(desc(lifeExp_mean)) %>%
  
  head()
## # A tibble: 6 × 2
##   country     lifeExp_mean
##   <fct>              <dbl>
## 1 Iceland             76.5
## 2 Sweden              76.2
## 3 Norway              75.8
## 4 Netherlands         75.6
## 5 Switzerland         75.6
## 6 Canada              74.9

Dans la période considérée, c’est l’Island qui a en moyenne la plus grande espérance de vie. Elle est suivie par la Suède.

Il est possible de calculer plus d’une statistique récapitulative après avoir groupé les données selon une variable catégorielle. Reprenons le code ci-dessus et calculons l’espérance de vie médiane :

gapminder %>%
  
  select(c('country', 'lifeExp')) %>%
  
  group_by(country) %>%
  
  summarise(lifeExp_mean = mean(lifeExp), 
            lifeExp_median = median(lifeExp)) %>%
  
  arrange(desc(lifeExp_mean)) %>%
  
  head()
## # A tibble: 6 × 3
##   country     lifeExp_mean lifeExp_median
##   <fct>              <dbl>          <dbl>
## 1 Iceland             76.5           76.6
## 2 Sweden              76.2           75.9
## 3 Norway              75.8           75.6
## 4 Netherlands         75.6           75.6
## 5 Switzerland         75.6           75.8
## 6 Canada              74.9           75.0

8.2 Visualisation des données avec ggplot2

La visualisation permet d’explorer les données et de fournir des informations utiles pour la décision. De bonnes visualisations vous aident également à communiquer vos données à d’autres et sont utiles aux spécialistes de la data et aux autres consommateurs des données.

ggplot2 est une puissante bibliothèque de R et fait partie des packages de Tidyverse. Utilisée par des centaines de milliers de Data Scientists, cette librairie facilite la création de graphiques informatifs et attrayants. Dans cette section vous apprendrez à créer des graphiques courants tels que les nuages de points, les histogrammes, les boîtes à moustache, les diagrammes à barres, etc. De plus, vous apprendrez à personnaliser vos graphiques afin d’en faciliter la lecture à vos interlocuteurs ce qui vous permettra de mieux communiquer les résultats de vos analyses.

Si vous avez déjà installé et importé Tidyverse, vous n’avez donc plus besoin d’installer et d’importer ggplot2.

8.2.1 Nuage de points

Un nuage de points est un graphique très courant et facile à construire qui permet de comprendre la relation existante entre des données bivariées quantitatives. A partir des données de gapminder (Voir Section précédente), traçons le nuage de points montrant la relation entre l’espérance de vie et le PIB par habitant :

# Espérance de vie en fonction du PIB par habitant

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  
  geom_point()

C’est la fonction geom_point() qui permet d’ajouter le nuage de points au graphique. Pour une bonne compréhension, il est important d’ajouter un titre au graphique et de nommer convenablement les axes :

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant")

Ce nuage de points montre que la relation existant entre l’espérance de vie et le PIB n’est pas une relation linéaire. Dans ce genre de cas, il est souvent utile de travailler avec une échelle logarithmique :

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant") +
  
  # Transformation logarithmique de l'axe des abscisses
  
  scale_x_log10()

Dans le graphique ci-dessus, chaque unité sur l’axe des abscisses représente un changement de 10 fois le PIB. Les points sont beaucoup plus répartis sur le graphique et la relation entre les deux variables semble être linéaire. Vous pouvez même ajouter une droite de régression au nuage de points :

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant") +
  
  # Transformation logarithmique de l'axe des abscisses
  
  scale_x_log10() +
  
  # Ajout d'une droite de régression sans intervalle de confiance
  
  geom_smooth(method = "lm", se = FALSE)

Dans la fonction aes(), vous pouvez ajouter d’autres arguments comme l’argument color qui permet de colorier les points. Ici, nous pouvons colorier les points selon les continents. En effet, un meilleur moyen de représenter une variable catégorielle dans un nuage de points est de l’utiliser pour définir les couleurs des points :

ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, color = continent)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant") +
  
  # Transformation logarithmique de l'axe des abscisses
  
  scale_x_log10()

Comme vous le constatez, une légende a été ajoutée automatiquement indiquant la couleur de chaque continent. D’après ce graphique, l’eespérance de vie moyenne et le PIB par habitant ont tendance à être les plus bas pour les pays africains (points en rouge) et les plus élevés pour les pays européens (points en bleu).

N.B : Pour transformer l’axe des ordonnées en une échelle logarithmique, ajoutez plutôt scale_y_log10().

On peut aussi spécifier la taille des points à l’aide de l’argument size de la fonction aes() en utilisant une variable numérique de l’ensemble des données :

ggplot(data = gapminder, 
       aes(x = gdpPercap, y = lifeExp, 
           color = continent, size = pop)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant") +
  
  # Transformation logarithmique de l'axe des abscisses
  
  scale_x_log10()

La légende de l’argument size a été aussi automatiquement généré. Le graphique ci-dessus permet d’analyser les relations entre quatre (04) variables (l’espérance de vie, le PIB par habitant, la population et les continents). Il ressort de ce graphique que ce sont certains pays asiatiques qui ont les plus grandes populations.

Vous pouvez aussi tracer un nuage de point montrant l’espérance de vie en fonction du PIB par habitant pour chaque année.

# Nombre total des années

length(unique(gapminder$year))
## [1] 12

Il y a 12 années distinctes dans le jeu de données gapminder donc il serait fastidieux de tracer 12 graphiques. Il existe un moyen très simple (facet_wrap) de tracer des sous-graphiques (subplots en Anglais) dans ggplot2 :

ggplot(data = gapminder, 
       aes(x = gdpPercap, y = lifeExp, 
           color = continent, size = pop)) +
  
  geom_point() +
  
  labs(x = "PIB par habitant",
       
       y = "Espérance de vie", 
       
       title = "Relation entre l'espérance de vie et le PIB par habitant") +
  
  # Transformation logarithmique de l'axe des abscisses
  
  scale_x_log10() +
  
  # Ajout des sous-graphiques
  
  facet_wrap(~ year)

N.B : La variable a l’intérieur de la fonction facet_wrap() doit être une variable discrète (c’est-à-dire avec un nombre fini de modalités).

8.3 Diagramme à barres

On utilise un diagramme pour visualiser les variables catégorielles. En effet, le diagramme à barre est un meilleur choix pour comparer une statistique pour chacune des modalités d’une variable catégorielle. Pour tracer un diagramme à barres avec ggplot2, utilisez la fonction geom_bar() :

# Diagramme montrant le nombre d'observations de chaque continent

ggplot(gapminder, aes(continent)) +
  
  geom_bar() +
  
  labs(x = "Continent", y = "Nombre",
       
       title = "Nombre d'observations de chaque continent")

En utilisant l’argument fill dans aes(), on peut définir une couleur pour les barres :

# Diagramme montrant le nombre d'observations dans chaque continent

ggplot(gapminder, aes(continent, fill = continent)) +
  
  geom_bar() +
  
  labs(x = "Continent", y = "Nombre",
       
       title = "Nombre d'observations dans chaque continent")

Vous pouvez aussi représenter, par un diagramme à barres une variable quantitative en fonction d’une variable catégorielle. Ce type de diagramme à barres se trace avec la fonction geom_col() :

# Population totale par continent

pop_total_df <- gapminder %>%
  
  group_by(continent) %>%
  
  summarise(total_pop = sum(pop))

pop_total_df
## # A tibble: 5 × 2
##   continent   total_pop
##   <fct>           <dbl>
## 1 Africa     6187585961
## 2 Americas   7351438499
## 3 Asia      30507333901
## 4 Europe     6181115304
## 5 Oceania     212992136

A partir de la table ci-dessus, traçons le diagramme à barre :

ggplot(pop_total_df, aes(continent, total_pop, fill = continent)) +
  
  geom_col()

Sans surprise, l’Asie a la population la plus grande dépassant de très loin les autres contients.

8.4 Graphiques linéaires

Les graphiques linéaires sont mieux adaptés pour visualiser les changements au niveau des séries temporelles comme par exemple l’évolution de l’espérance de vie moyenne au fil du temps :

mean_life_exp_by_year <- gapminder %>%
  
  group_by(year) %>%
  
  summarise(lifeExp_mean = mean(lifeExp))

mean_life_exp_by_year
## # A tibble: 12 × 2
##     year lifeExp_mean
##    <int>        <dbl>
##  1  1952         49.1
##  2  1957         51.5
##  3  1962         53.6
##  4  1967         55.7
##  5  1972         57.6
##  6  1977         59.6
##  7  1982         61.5
##  8  1987         63.2
##  9  1992         64.2
## 10  1997         65.0
## 11  2002         65.7
## 12  2007         67.0

Traçons à présent une courbe montrant l’évolution de l’espérance de vie moyenne au cours du temps :

ggplot(mean_life_exp_by_year, aes(year, lifeExp_mean)) +
  
  geom_line() +
  
  labs(x = "Année", y = "Espérance de vie moyenne", 
       
       title = "Evolution de l'espérance de vie moyenne au cours du temps")

Nous pouvons aussi tracer l’évolution de l’espérance de vie moyenne pour chacun des continents :

mean_life_exp_by_cont_year <- gapminder %>%
  
  group_by(continent, year) %>%
  
  summarize(lifeExp_mean = mean(lifeExp))

head(mean_life_exp_by_cont_year)
## # A tibble: 6 × 3
## # Groups:   continent [1]
##   continent  year lifeExp_mean
##   <fct>     <int>        <dbl>
## 1 Africa     1952         39.1
## 2 Africa     1957         41.3
## 3 Africa     1962         43.3
## 4 Africa     1967         45.3
## 5 Africa     1972         47.5
## 6 Africa     1977         49.6
ggplot(mean_life_exp_by_cont_year, aes(year, lifeExp_mean, col = continent)) +
  
  geom_line() +
  
  labs(x = "Année", y = "Espérance de vie moyenne",
       
       title = "Evolution de l'espérance de vie moyenne par continent")

Nous aurions pu utiliser des sous-graphiques avec la fonction facet_wrap() :

ggplot(mean_life_exp_by_cont_year, aes(year, lifeExp_mean, fill = continent)) +
  
  geom_line() +
  
  labs(x = "Année", y = "Espérance de vie moyenne",
       
       title = "Evolution de l'espérance de vie moyenne par continent") +
  
  facet_wrap(~ continent)

8.4.1 Exercice d’application

Tracez un graphique linéaire montrant l’évolution de la population totale pour chaque continent :

# Création de la dataframe

pop_total_by_year <- gapminder %>%
  
  group_by(continent, year) %>%
  
  summarise(total_pop = sum(pop))

head(pop_total_by_year)
## # A tibble: 6 × 3
## # Groups:   continent [1]
##   continent  year total_pop
##   <fct>     <int>     <dbl>
## 1 Africa     1952 237640501
## 2 Africa     1957 264837738
## 3 Africa     1962 296516865
## 4 Africa     1967 335289489
## 5 Africa     1972 379879541
## 6 Africa     1977 433061021
ggplot(pop_total_by_year, aes(year, total_pop, col = continent)) +
  
  geom_line() +
  
  labs(x = "Année", y = "Population total",
       
       title = "Evolution de la population totale par continent")

8.5 Histogrammes

Un histogramme prend un ensemble de points de données et les sépare en groupes ou plage de valeurs. Les histogrammes sont utilisés pour visualiser la distribution des variables numériques. Pour tracer un histogramme dans ggplot2, vous devez utiliser la fonction geom_histogram() :

# Histogramme de l'espérance de vie moyenne

ggplot(gapminder, aes(lifeExp)) +
  
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

En abscisse, on a les valeurs de la variable regroupées dans des bacs (bins en Anglais). Vous pouvez spécifier le nombre de bins que vous voulez en utilisant l’argument bindwidths. Les hauteurs des barres représentent le nombre de points de données qui entrent dans un bac :

# Histogramme de l'espérance de vie moyenne

ggplot(gapminder, aes(lifeExp)) +
  
  geom_histogram(binwidth = 10)

Le nombre de bins peut modifier l’apparence de l’histogramme. Par ailleurs, vous pouvez ajouter des couleurs à un histogramme. Par exemple, il est possible de discrétiser l’histogramme de l’espérance de vie moyenne selon le continent :

# Histogramme de l'espérance de vie moyenne pour chaque continent

ggplot(gapminder, aes(lifeExp, fill = continent)) +
  
  geom_histogram(position = "fill")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 5 rows containing missing values (`geom_bar()`).

Vous pouvez aussi choisir de représenter uniquement la densité de probabilité en utilisant la fonction geom_density() :

# Densité de probabilité de l'espérance de vie moyenne

ggplot(gapminder, aes(lifeExp)) +
  
  geom_density()

Vous pouvez aussi tracer dans un même graphique l’histogramme ainsi que la densité de probabilité d’une variable. Il suffit d’ajouter deux couches à votre graphique :

  • une première couche avec geom_histogram. A l’intérieur de la fonction aes() de geom_histogram, vous devez ajouter le code y = ..density.. ;

  • une deucième couche avec geom_density pour afficher la densité de probabilité.

# Histograme + Densité de probabilité de l'espérance de vie moyenne

ggplot(gapminder, aes(lifeExp)) +
  
  geom_histogram(aes(y = ..density..), colour= "black", fill = "white") +
  
  geom_density(fill="blue", alpha = .2)
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Passons maintenant à la description d’un histogramme.

Pour décrire un histogramme, vous devez faire ressortir nécessairement 04 aspects importants :

  • forme de l’histogramme : c’est l’apparence globale de l’histogramme. Vous devez dire si elle est symétrique, en forme de cloche (loi normale), asymétrique positive (c’est-à-dire forme étalée vers la droite) ou asymétrie négative (c’est-à-dire forme étalée vers la gauche.) ;

  • centre de la distribution : médiane ;

  • dispersion des valeurs : à ce niveau, vous devez interpréter la variabilité dans les données en utilisant la variance, l’écart-type ou l’IQR ou Inter Quartile Range. La gamme interquartile est égale à la différence entre le troisième quartile et le premier quartile ;

  • outliers (en Anglais) ou valeurs aberrantes : ce sont des valeurs qui sortent du lot c’est-à-dire qui sont très loin du centre de gravité des données. Une règle souvent utilisée est que toute valeur respectant cette condition est un outlier : \[data < Q1 - 1,5 IQR\] ou \[data > Q3 + 1,5 IQR\].

Faisons un petit rappel sur la loi normale.

La distribution normale est l’une des plus importantes distributions. C’est une notion centrale en Statistique et en Data Science. Sans faire ici un cours théorique sur la loi normale, voici quelques caractéristiques d’une distribution normale :

  • forme en cloche ;

  • distribution symétrique (donc le coefficient d’asymétrie est égal à 0) ;

  • La moyenne est égale à la médiane.

# Exemple d'une loi normale centrée réduite de taille 10000

data_norm <- rnorm(n = 10000, mean = 0, sd = 1)

# Transformation en dataframe

data_norm <- data.frame(data_norm)

names(data_norm) <- c('Variable')

# Histogramme et Densité de probabilité

ggplot(data_norm, aes(Variable)) +
  
  geom_histogram(aes(y = ..density..), colour= "black", fill = "white") +
  
  geom_density(fill="blue", alpha = .2) +
  
  labs(title = 'Loi normale centrée réduite de taille 10000')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Voici une description de la distribution ci-dessus :

La distribution ci-dessus est unimodale et symétrique et centrée (moyenne égale à la médiane) avec la plupart des données entre -2,5 et 2,5 et aucune valeur aberrante.

8.6 Boîtes à moustache

Comme les histogrammes, les boîtes à moustaches servent aussi à représenter la distribution des variables numériques. Les histogrammes sont meilleurs pour montrer la forme d’une distribution ; les boîtes à moustache aident à mieux identifier les valeurs aberrantes. Par ailleurs, l’autre avantage des boîtes à moustache est qu’elles peuvent être utilisées pour représenter facilement la distribution d’une variable continue en fonction d’une variable catégorielle. La figure ci-dessous présente les valeurs clés qu’on peut lire dans une une boîte à moustache :

Pour tracer les boîtes à moustache avec ggplot2, vous devez utiliser la fonction geom_boxplot() :

# Répartition des espérances de vie entre les continents

ggplot(gapminder, aes(continent, lifeExp)) +
  
  geom_boxplot() +
  
  labs(title = 'Répartition des espérances de vie entre les continents')

On remarque que l’espérance de vie moyenne en Afrique est la plus faible tandis que l’Europe et l’Océanie sont pratiquement au même niveau. De plus, il y a quelques valeurs aberantes au niveau de la distribution de l’espérance de vie en Europe. On note aussi que la ligne médiane au niveau des Amériques est loin du milieu ce qui indique une distribution asymétrique.

Il est possible de colorier aussi les boîtes à moustache :

# Répartition des espérances de vie entre les continents

ggplot(gapminder, aes(continent, lifeExp, fill = continent)) +
  
  geom_boxplot() +
  
  labs(title = 'Répartition des espérances de vie entre les continents')

On peut aussi représenter l’espérance de vie par année. Il suffit de transformer la variable year en une variable catégorielle à l’aide de la fonction factor() :

# Boîtes à moustache de l'espérance de vie par année

ggplot(gapminder, aes(factor(year), lifeExp, fill = factor(year))) +
  
  geom_boxplot() +
  
  labs(title = 'Répartition des espérances de vie entre les continents')

Ce graphique confirme l’information obtenue avec le graphique linéaire montrant l’évolution de l’évolution de l’espérance de vie sur le plan mondial. En effet, nous constatons ici une croissance de l’espérance de vie médiane eu cours du temps.

8.7 Manipulation des variables catégorielles avec Tidyverse

Une variable est dite qualitative quand les valeurs possibles qu’elle peut prendre (c’est-à-dire ses modalités) ne sont pas numériques. Dans le groupe des variables qualitatives, on a encore deux sous-catégories : les variables qualitatives nominales ou catégorielles et les variables qualitatives ordinales.

Une variable qualitative est dite nominale quand ses modalités ne peuvent pas être ordonnées. Une variable qualitative est dite ordinale quand ses modalités peuvent être ordonnées. Dans R, les variables qualitatives peuvent être représentées en tant que caractères et en tant que facteurs. R détecte automatiquement le type de chaque variable qualitative (character ou factor) dans une dataframe.

Dans cette section, vous apprendrez à manipuler les variabes qualitatives en utilisant principalement le package forcats de la librairie Tidyverse.

Afin d’illustrer les différents concepts, nous utiliserons l’ensemble des données multipleChoiceResponses provenant de Kaggle. La version originale de cet ensemble de données contient 228 variables. Dans cette section, noous utiliserons une version simplifiée contenant 47 variables que vous pouvez trouver sur GitHub.

# Importation des données

kaggle_survey <- read.csv('kaggle_2017_survey.txt')
## Warning in file(file, "rt"): impossible d'ouvrir le fichier
## 'kaggle_2017_survey.txt' : No such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
head(kaggle_survey)
## Error in head(kaggle_survey): objet 'kaggle_survey' introuvable
# Structure interne de l'ensemble des données

str(kaggle_survey)
## Error in str(kaggle_survey): objet 'kaggle_survey' introuvable

Cet ensemble de données a été construit suite à une enquête qui a permi d’interroger des milliers de spécialistes de la Data Science.

Est-ce que l’ensemble des données contient des données de type facteur (factor) ?

# Variables de type 'factor'

kaggle_survey %>%
  
  select_if(is.factor) %>%

  names()
## Error in tbl_vars_dispatch(x): objet 'kaggle_survey' introuvable

il n’y a pas de variables de type facteur. Comme le montre le résultat ci-dessous, toutes les variables qualitatives de ce jeu de données sont de type caractère (character) :

# Variables de type 'factor'

kaggle_survey %>%
  
  select_if(is.character) %>%

  names()
## Error in tbl_vars_dispatch(x): objet 'kaggle_survey' introuvable

Supposons que vous voulez convertir les variables ci-dessus en facteur. Pour ce faire, vous pouvez utiliser la fonction mutate_if() :

# Conversion de variables de type caractère en type facteur

kaggle_survey2 <- kaggle_survey %>%
  
  mutate_if(is.character, as.factor) 
## Error in is_grouped_df(tbl): objet 'kaggle_survey' introuvable
str(kaggle_survey2)
## Error in str(kaggle_survey2): objet 'kaggle_survey2' introuvable

Pour connaître les modalités d’une variable catégorielle de type factor, vous pouvez utiliser la fonction levels(). La variable CurrentJobTitleSelect indique le titre de la personne interrogée :

# Modalités de la variable 'CurrentJobTitleSelect'

levels(kaggle_survey2$CurrentJobTitleSelect)
## Error in levels(kaggle_survey2$CurrentJobTitleSelect): objet 'kaggle_survey2' introuvable

La variable CurrentJobTitleSelect contient 16 modalités (ou niveaux). Vous pouvez retrouver ce nombre en utilisant la fonction nlevels :

# Nombre de modalités de la variable 'CurrentJobTitleSelect'

nlevels(kaggle_survey2$CurrentJobTitleSelect)
## Error in levels(x): objet 'kaggle_survey2' introuvable

Vous pouvez afficher le nombre de modalités dans chaque variable catégorielle en exécutant le code ci-dessous :

kaggle_survey2 %>%
  
  summarise_if(is.factor, nlevels)
## Error in tbl_vars_dispatch(x): objet 'kaggle_survey2' introuvable

Quel est le titre le plus populaire parmi les métiers en Science des Données (Data Science) ? Pour répondre à cette question, nous pouvons tracer un diagramme à barres :

# Diagramme à barre des métiers en Science des données

ggplot(kaggle_survey2) +
  
  geom_bar(aes(CurrentJobTitleSelect)) +
  
  labs(x  = "Métier", title = "Métiers en Data Science") +
  
  coord_flip()
## Error in ggplot(kaggle_survey2): objet 'kaggle_survey2' introuvable

En dehors des valeurs manquantes, Data Scientist est le titre de métier le plus populaire en Science des données. Pour rendre le graphique beaucoup plus facile à lire, vous pouvez ordonner les modalités par ordre croissant ou décroissant de leurs fréquences. Les fonctions fct_infreq() et fct_rev() du package forcats permettent de réaliser ces opérations :

# Diagramme à barre des métiers en Science des données
  # Affichage des modalités par ordre croissant des fréquences

ggplot(kaggle_survey2) +
  
  geom_bar(aes(fct_infreq(CurrentJobTitleSelect))) +
  
  labs(x  = "Métier", title = "Métiers en Data Science") +
  
  coord_flip()
## Error in ggplot(kaggle_survey2): objet 'kaggle_survey2' introuvable

On peut aussi avoir un affichage par ordre décroissant des fréquences des modalités :

# Diagramme à barre des métiers en Science des données
  # Affichage des modalités par ordre décroissant des fréquences

ggplot(kaggle_survey2) +
  
  geom_bar(aes(fct_rev(fct_infreq(CurrentJobTitleSelect)))) +
  
  labs(x  = "Métier", title = "Métiers en Data Science") +
  
  coord_flip()
## Error in ggplot(kaggle_survey2): objet 'kaggle_survey2' introuvable

Il arrive parfois que les modalités d’une variable qualitative ne n’ont pas les noms que nous voulons.

Quels sont les niveaux d’éducation des spécialistes de la Science des données dans leurs boulots ?

levels(kaggle_survey2$FormalEducation)
## Error in levels(kaggle_survey2$FormalEducation): objet 'kaggle_survey2' introuvable

Vous pouvez renommer tout ou quelques-unes de ces modalités. La fonction fct_recode() permet de renommer les niveaux des variables de type facteur :

kaggle_survey2 <- kaggle_survey2 %>%
  
  mutate(FormalEducation = fct_recode(FormalEducation, 
                                      
                                      "phD" = "Doctoral degree",
                                      
                                      "Master" = "Master's degree"))
## Error in mutate(., FormalEducation = fct_recode(FormalEducation, phD = "Doctoral degree", : objet 'kaggle_survey2' introuvable
# Vérification 

levels(kaggle_survey2$FormalEducation)
## Error in levels(kaggle_survey2$FormalEducation): objet 'kaggle_survey2' introuvable

Comme vous le constatez les anciens niveaux “Doctoral degree” et “Master’s degree” ont été respectivement renommés en “phD” et “Master.

Parfois, une variable qualitative peut contenir trop de modalités ce qui complique un peu son analyse. L’une des solutions dans ce cas est de de regrouper certaines modalités en une seule modalité.

Il y a 16 titres de poste (y compris «other») que les gens pourraient sélectionner dans le sondage. Regroupons-les en quatre grandes catégories : “Computer Scientist”, “Data analyst/scientist/engineer”, “Researcher,” et “Other”.

kaggle_survey2 %>%
  
    # Création d'une nouvelle variable
  
    mutate(CurrentJobTitleGroups = fct_collapse(
      
      CurrentJobTitleSelect, 
      
      "Computer Scientist" = c(
        "Programmer", 
        "Software Developer/Software Engineer"
        ), 
      
      "Researcher" = "Scientist/Researcher", 
      
      "Data Analyst/Scientist/Engineer" = c(
        "DBA/Database Engineer", 
        "Data Scientist", 
        "Business Analyst", 
        "Data Analyst", 
        "Data Miner", "Predictive Modeler"
        )
      )
      ) %>%
  
    
    # Création d'un diagramme à barre
  
    ggplot() + geom_bar(
      aes(fct_rev(fct_infreq(CurrentJobTitleGroups)), 
          fill = CurrentJobTitleGroups)
      ) + 
  
    coord_flip() +
  
    labs(x = 'Groupes de métiers')
## Error in mutate(., CurrentJobTitleGroups = fct_collapse(CurrentJobTitleSelect, : objet 'kaggle_survey2' introuvable

9 Chapitre 6 : Jointure des données avec dplyr

Très souvent, les données sont réparties dans plusieurs tables. Dans ce cas, une analyse efficace de l’ensemble de ces données nécessite la jointure des tables. Dans ce chapitre, vous apprendrez six (06) différents types de jointure : inner join, left join, right join, full join, semi join et anti join en utilisant le package dplyr.

dplyr est un composant de Tidyverse donc si vous aviez déjà importer Tidyverse, plus besoin d’importer dplyr.

# Importation de dplyr

library(dplyr)

Pour pratiquer les différents types de jointure, nous utiliserons l’ensemble des données sur les jouets de construction appelé LEGO qui contient différentrs types d’informations (couleurs, thèmes, etc.) réparties dans plusieurs tables.

9.1 Jointure interne (inner join)

Le fichier ‘sets.rds’ contient des informations sur les différents ensembles de LEGO. Nous pouvons importer les fichiers rds avec la fonction readRDS() :

# Ensembles de LEGO

lego_sets <- readRDS('sets.rds')
## Warning in gzfile(file, "rb"): impossible d'ouvrir le fichier compressé
## 'sets.rds', cause probable : 'No such file or directory'
## Error in gzfile(file, "rb"): impossible d'ouvrir la connexion
head(lego_sets)
## Error in head(lego_sets): objet 'lego_sets' introuvable
# Structure de lego_sets

str(lego_sets)
## Error in str(lego_sets): objet 'lego_sets' introuvable

Chacune des 4977 lignes représente un ensemble de jeu LEGO caractérisé par quatre (04) variables.

Le fichier ‘themes.rds’ contient les donnée sur les thèmes de jeu de LEGO :

# Thèmes de LEGO

themes_lego <- readRDS('themes.rds')
## Warning in gzfile(file, "rb"): impossible d'ouvrir le fichier compressé
## 'themes.rds', cause probable : 'No such file or directory'
## Error in gzfile(file, "rb"): impossible d'ouvrir la connexion
head(themes_lego)
## Error in head(themes_lego): objet 'themes_lego' introuvable
# Structure de la table themes_lego

str(themes_lego)
## Error in str(themes_lego): objet 'themes_lego' introuvable

la variable theme_id dans la table lego_sets est liée à la variable id dans la table themes_lego. Pour trouver le thème correspondant à chacun des ensembles de jeu LEGO, nous devons joindre les deux tables. Pour ce faire, utilisons une jointure interne avec la fonction inner_join() de dplyr. La jointure interne de deux tables A et B permet de créer une nouvelle table contenant des observations qui sont à la fois présentes dans A et dans B.

# Jointure interne des tables lego_sets et themes

sets_themes <- lego_sets %>%
  
  inner_join(themes_lego, by = c("theme_id" = "id"))
## Error in inner_join(., themes_lego, by = c(theme_id = "id")): objet 'lego_sets' introuvable

Le code ci-dessus permet de joindre la première table lego_sets à la deuxième table themes. L’argument by permet d’indiquer à la jointure comment lier les deux tables. Ici, il s’agit de lier l’identifiant du thème (theme_id) dans la première table à l’identifiant du thème (id) dans la deuxième table. Le résultat est présenté ci-dessous :

head(sets_themes)
## Error in head(sets_themes): objet 'sets_themes' introuvable

Dans la table ci-dessus, vous remarquez les noms de variable ‘name.x’ et ‘name.y’. En effet, les deux tables lego_sets et themes_lego ont toutes deux une variable appelée name. Donc, de manière automatique, la variable ‘name’ de la table lego_sets a été renommée ‘name.x’ et celle de la table themes_lego a été renommée ‘name.y’ au niveau de la table sets_themes. Nous pouvons personnaliser la jointure interne pour obtenir un résultat beaucoup plus lisible. Nous ajouterons l’argument suffix. L’argument suffix permet d’ajouter un suffixe aux noms des colonnes partagées :

# Personnalisation de la jointure interne des tables lego_sets et themes

sets_themes <- lego_sets %>%
  
  inner_join(themes_lego, 
             
             by = c("theme_id" = "id"), 
             
             suffix = c("_set", "_theme"))
## Error in inner_join(., themes_lego, by = c(theme_id = "id"), suffix = c("_set", : objet 'lego_sets' introuvable
head(sets_themes)
## Error in head(sets_themes): objet 'sets_themes' introuvable

A présent, il est possible de répondre à des questions intéressantes concernant les jeux LEGO. Par exemple, quels sont les dix (10) thèmes les plus courants dans les jeux LEGO ? Nous utiliserons la fonction count() :

sets_themes %>%
  
  count(name_theme, sort = TRUE) %>%
  
  head(10)
## Error in count(., name_theme, sort = TRUE): objet 'sets_themes' introuvable

N.B : Une jointure interne fonctionne de la même manière avec l’une ou l’autre des tables dans les deux positions. La table spécifiée en premier est arbitraire, car vous vous retrouverez avec les mêmes informations dans la table résultante dans les deux cas.

9.1.1 Exercice d’application

Après avoir importer les fichiers ‘parts.rds’ et part_categories.rds, déterminez les colonnes contituant le lien entre les deux tables et effectuez leur jointure interne.

# Importation du fichier 'parts.rds'

parts_lego <- readRDS('parts.rds')
## Warning in gzfile(file, "rb"): impossible d'ouvrir le fichier compressé
## 'parts.rds', cause probable : 'No such file or directory'
## Error in gzfile(file, "rb"): impossible d'ouvrir la connexion
head(parts_lego)
## Error in head(parts_lego): objet 'parts_lego' introuvable
# Importation du fichier 'part_categories.rds'

categories_lego <- readRDS('part_categories.rds')
## Warning in gzfile(file, "rb"): impossible d'ouvrir le fichier compressé
## 'part_categories.rds', cause probable : 'No such file or directory'
## Error in gzfile(file, "rb"): impossible d'ouvrir la connexion
head(categories_lego)
## Error in head(categories_lego): objet 'categories_lego' introuvable

Les colonnes sur lesquelles on peut joindre ces deux tables sont : ‘part_cat_id’ (de la table parts_lego) et ‘id’ (de la table categories_lego) :

# Jointure interne des deux tables

parts_cats <- parts_lego %>%
  
  inner_join(categories_lego, 
             
             by = c("part_cat_id" = "id"), 
             
             suffix = c("_part", "_categorie"))
## Error in inner_join(., categories_lego, by = c(part_cat_id = "id"), suffix = c("_part", : objet 'parts_lego' introuvable
head(parts_cats)
## Error in head(parts_cats): objet 'parts_cats' introuvable

9.2 Jointure à gauche (left_join)

La jointure à gauche permet de conserver toutes les observations dans la première table (ou table de gauche) qu’elles apparaissent ou non dans la deuxième table (ou table de droite). Par conséquent, des valeurs manquantes peuvent apparaître au niveau du résultat.

Dans cette section, nous explorerons les données des fichiers ‘batmobile_lego.csv’ et ‘batwing_lego.csv’. Ces fichiers concernent respectivement la batmobile et la batwing qui sont toutes deux des voitures appartenant au super-héros Batman.

La batmobile est une voiture qui ne peut voler tandis que la batwing peut voler.

Nous voulons voir quelles pièces sont incluses dans l’un de leurs ensembles LEGO mais pas dans l’autre.

Commençons par importer les données :

# Importation du fichier 'batwing_lego.csv'

batwing <- read.csv('batwing_lego.csv')
## Warning in file(file, "rt"): impossible d'ouvrir le fichier 'batwing_lego.csv' :
## No such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
head(batwing)
## Error in head(batwing): objet 'batwing' introuvable
# Importation du fichier 'batmobile_lego.csv'

batmobile <- read.csv('batmobile_lego.csv')
## Warning in file(file, "rt"): impossible d'ouvrir le fichier
## 'batmobile_lego.csv' : No such file or directory
## Error in file(file, "rt"): impossible d'ouvrir la connexion
head(batmobile)
## Error in head(batmobile): objet 'batmobile' introuvable

batwing et batmobile sont deux tables contenant chacune trois (03) variables. Chaque observation est une pièce LEGO. Une pièce LEGO est une combinaison d’une pièce et d’une couleur comme le montre l’image ci-dessous :

Nous voulons connaître les pièces qui sont dans la batmobile mais pas dans la batwing. Nous pouvons utiliser une jointure à gauche :

# Jointure à gauche de la batmobile à la batwing

mob_wing <- batmobile %>%  
  
  left_join(batwing, by = c("part_num", "color_id"), 
            suffix = c("_batmobile", "_batwing"))
## Error in left_join(., batwing, by = c("part_num", "color_id"), suffix = c("_batmobile", : objet 'batmobile' introuvable
head(mob_wing, 10)
## Error in head(mob_wing, 10): objet 'mob_wing' introuvable

Vous remarquez que la colonne ‘quantity_batwing’ contient désormais des valeurs manquantes représentées par des NA. Ce qui veut dire qu’il y a des pièces qui constituent la batmobile mais ne font pas partie de la batwing. Par exemple la pièce numéro 3010 et dont l’identifiant de la couleur est 0 apparaît 21 fois dans la batmobile mais n’apparaît jamais dans la batwing.

9.2.1 Exercice d’application

A l’aide d’une jointure à gauche, trouvez les pièces qui apparaissent dans la batwing mais n’apparaissent jamais dans la batmobile.

# Jointure à gauche de la batwing à la batmobile

wing_mob <- batwing %>%  
  
  left_join(batmobile, by = c("part_num", "color_id"), 
            suffix = c("_batwing", "_batmobile"))
## Error in left_join(., batmobile, by = c("part_num", "color_id"), suffix = c("_batwing", : objet 'batwing' introuvable
head(wing_mob, 10)
## Error in head(wing_mob, 10): objet 'wing_mob' introuvable

Par exemple la pièce numéro 99207 et dont l’identifiant de la couleur est 71 apparaît 18 fois dans la batmwing mais n’apparaît jamais dans la batmobile.

9.3 Jointure à droite (right join)

La jointure à droite permet de conserver toutes les observations dans la deuxième table (ou table de droite) qu’elles apparaissent ou non dans la première table (ou table de gauche). Par conséquent, des valeurs manquantes peuvent apparaître au niveau du résultat. Le code ci-dessous permet de retrouver les pièces qui sont dans LEGO batwing et qui ne sont pas dans LEGO batmobile :

# Jointure à droite de batmobile à batwing

bat_wing_right <- batmobile %>%  
  
  right_join(batwing, by = c("part_num", "color_id"), 
             suffix = c("_batmobile", "_batwing"))
## Error in right_join(., batwing, by = c("part_num", "color_id"), suffix = c("_batmobile", : objet 'batmobile' introuvable
# Affichage des 10 dernières lignes avec la fonction tail()

tail(bat_wing_right, 10)
## Error in tail(bat_wing_right, 10): objet 'bat_wing_right' introuvable

Dans l’exercice d’application précédent, nous avions déjà déterminé les pièces qui sont dans LEGO batwing et qui ne sont pas dans LEGO batmobile à l’aide d’une jointure à gauche. Les 10 dernières lignes de la table résultante de cette jointure à gauche sont :

tail(wing_mob, 10)
## Error in tail(wing_mob, 10): objet 'wing_mob' introuvable

Vous remarquez que les tables bat_wing_right et wing_mob sont équivalentes. En effet les jointures gauche et droite sont images l’une de l’autre.

9.3.1 Exercice d’application

A l’aide d’une jointure à droite, trouvez les pièces qui apparaissent dans LEGO batmobile mais n’apparaissent jamais dans LEGO batwing.

# Jointure à droite de batwing à batmobile

wing_bat_right <- batwing %>%  
  
  right_join(batmobile, by = c("part_num", "color_id"), 
             suffix = c("_batwing", "_batmobile"))
## Error in right_join(., batmobile, by = c("part_num", "color_id"), suffix = c("_batwing", : objet 'batwing' introuvable
# Affichage des 10 dernières lignes avec la fonction tail()

tail(wing_bat_right, 10)
## Error in tail(wing_bat_right, 10): objet 'wing_bat_right' introuvable

9.4 Jointure complète (full join)

Si vous voulez conserver toutes les observations présentes au niveau des deux tables, qu’elles correspondent ou non, alors vous devez réaliser une jointure complète en utilisant la fonction full_join().

# Jointure complète des tables batmobile et batwing

bat_wing_full <- batmobile %>%  
  
  full_join(batwing, by = c("part_num", "color_id"), 
            suffix = c("_batmobile", "_batwing"))
## Error in full_join(., batwing, by = c("part_num", "color_id"), suffix = c("_batmobile", : objet 'batmobile' introuvable
head(bat_wing_full, 10)
## Error in head(bat_wing_full, 10): objet 'bat_wing_full' introuvable
print(sum(is.na(bat_wing_full$quantity_batmobile)))
## Error in print(sum(is.na(bat_wing_full$quantity_batmobile))): objet 'bat_wing_full' introuvable
print(sum(is.na(bat_wing_full$quantity_batwing)))
## Error in print(sum(is.na(bat_wing_full$quantity_batwing))): objet 'bat_wing_full' introuvable

Le résultat de la jointure complète présente des valeurs manquantes (NA) aussi bien au niveau de la variable ‘quantity_batmobile’ qu’au niveau de la variable ‘quantity_batwing’.

# Dimension de la table batwing

print(dim(batwing))
## Error in print(dim(batwing)): objet 'batwing' introuvable
# Dimension de la table batmobile

print(dim(batmobile))
## Error in print(dim(batmobile)): objet 'batmobile' introuvable
# Dimension de la table bat_wing_full

print(dim(bat_wing_full))
## Error in print(dim(bat_wing_full)): objet 'bat_wing_full' introuvable

Remarquez qu’il y a 440 observations au niveau de la table complète ce qui dépasse le nombre de lignes dans l’une ou l’autre des deux tables d’origine. En effet, en effectuant une jointure complète des tables batmobile et batwing, c’est comme si vous aviez ouvert les deux boîtes de LEGO et les versez l’une à côté de l’autre.

9.5 Semi-join et Anti-join

Jusqu’à présent, vous avez découvert quatre (04) types de jointure :

  • Jointure interne avec la fonction inner_join() ;

  • Jointure à gauche avec la fonction left_join() ;

  • Jointure à droite avec la fonction right_join() ;

  • Jointure complète avec la fonction full_join().

Ces jointures sont dites jointures mutantes car elles combinent les variables des deux tables.

Dans cette section, vous apprendrez deux autres types de jointures dites jointures filtrantes : semi_join() et anti_join(). Une jointure filtrante conserve ou supprime les observations de la première table, mais elle n’ajoute pas de nouvelles variables. Une semi-jointure entre les tables X et Y permet de répondre à la question : quelles observations dans X sont également dans Y ? Une anti-jointure entre les tables X et Y permet de répondre à la question : quelles observations dans X ne sont pas dans Y ?

Commençons par la semi-jointure entre les tables batmobile et batwing :

# Semi-jointure entre les les tables batmobile et batwing

bat_wing_semi <- batmobile %>%  
  
  semi_join(batwing, by = c("color_id", "part_num"))
## Error in semi_join(., batwing, by = c("color_id", "part_num")): objet 'batmobile' introuvable
print(head(bat_wing_semi, 10))
## Error in head(bat_wing_semi, 10): objet 'bat_wing_semi' introuvable
print(dim(bat_wing_semi))
## Error in print(dim(bat_wing_semi)): objet 'bat_wing_semi' introuvable

La table ci-dessus nous donne les pièces utilisées dans LEGO batmobile qui sont également utilisées dans LEGO batwing. Cette semi-jointure prend parmi les 173 observations présentes dans la table batmobile et les réduit aux 45 pièces présentes également dans la table batwing. Notez que les 3 variables de table batmobile ont été conservées et que nous n’avions pas eu besoin de spécifier l’argument suffix dans le code.

Le contraire d’une semi-jointure est une anti-jointure :

# Anti-jointure entre les les tables batmobile et batwing

bat_wing_anti <- batmobile %>%  
  
  anti_join(batwing, by = c("color_id", "part_num"))
## Error in anti_join(., batwing, by = c("color_id", "part_num")): objet 'batmobile' introuvable
print(head(bat_wing_anti, 10))
## Error in head(bat_wing_anti, 10): objet 'bat_wing_anti' introuvable
print(dim(bat_wing_anti))
## Error in print(dim(bat_wing_anti)): objet 'bat_wing_anti' introuvable

La table ci-dessus nous donne les pièces utilisées dans LEGO batmobile qui ne sont pas utilisées dans LEGO batwing. Ces pièces sont au nombre de 128.

10 CONCLUSION GENERALE

EXCELLENT ! Vous êtes à présent initié à la programmation avec le langage R dans le cadre de la Science des Données (Data Science). vous êtes maintenant capables :

  • d’installer et de Configurer votre environnement de travail pour pouvoir écrire du code R ;

  • d’écrire votre premier programme (‘Hello World’) et d’effectuer des opérations basiques (Addition, Soustraction, Multipication, Division, Exponentiel, Modulo, etc.) ;

  • d’afficher les résultats d’un code en utilisant de différentes manières les fonctions print(), paste() et cat() ;

  • de créer des variables et de les réutiliser ;

  • de manipuler différents types de données tels que les entiers naturels, les booléens, les chaînes de caractères, les nombres décimaux, les matrices, les vecteurs, les listes, les dataframes, etc.

  • de créer une dataframe et de recueillir des informations concernant sa structure et son résumé statistique ;

  • de combiner des booléens, des opérateurs logiques et des opérateurs de comparaison ;

  • d’écrire du code propre et concis incluant des structures conditionnelles if, if…else, if…else if…else, des boucles for et while ;

  • d’utiliser les fonctions de la famille apply tels que lapply(), sapply() et vapply() ;

  • de créer vos propres fonctions et de les optimiser afin d’automatiser certaines tâches et rendre votre code réutilisable ;

  • de créer des listes de compréhension vous permettant d’écrire des boucles for plus ou moins complexes en une seule ligne de code ;

  • d’importer différents types de fichiers tels que Excel, CSV, txt, TSV, …;

  • d’importer des données provenant du web à partir des API (Application Programing Interface) et du WebScraping ;

  • de manipuler les données à la manière de Tidyverse avec les fonctions filter(), arrange(), mutate(), select(), summarise() et group_by() ;

  • de créer des graphiques tels que les nuages de points (avec droite de régression), les diagrammes à barres, les courbes, les histogrammes, les boîtes à moustache ainsi que des subplots (sous-graphiques) ;

  • de traiter les variables catégorielles en utilisant les fonctionnalités de la librairie forcats ;

  • d’effectuer des jointures de tables (jointure interne, à gauche, à droite, complète ainsi qu’une semi-jointure et une anti-jointure) avec la librairie dplyr.

Ne vous arrêtez pas en si bon chemin car la programmation est une question de pratique quotidienne. Alors, pratiquez, pratiquez et pratiquez encore jusqu’à acquérir un certain automatisme.

11 Chapitre 7 : Mes autres livres et formations

Ci-dessous quelques livres qui vous permettront de développer des compétences nécessaires en Data Science :

Statistique et Simulation avec Python : Cours et Exercices corrigés

Broché : 288 pages ISBN-13 : 979-8591390259

La Statistique est présente partout dans notre quotidien. Vous ne pouvez pas y échapper. La Statistique est la fondation de la Data Science.

Ce livre vous donnera beaucoup de plaisir à réaliser des analyses statistiques avec le langage Python. Il n’est pas du tout comme la plupart des livres de Statistique retrouvés sur le marché qui sont remplis de théories et de formules mathématiques tellement complexes que cela ne donne pas envie de les lire. Mon livre à moi est écrit dans un langage très simple et accessible à tout le monde. Nul besoin d’avoir un Master ou un Doctorat en Mathématiques pour comprendre tous les concepts présentés dans ce livre. Chaque notion est présentée sous forme d’activité résolue avec cas pratique. Le code est écrit de manière très simple avec des commentaires. De plus, des exercices sont glissés après chaque concept introduit pour vous aider à pratiquer au fur à mesure ce que vous apprenez. Tous les exercices sont entièrement résolus au dernier chapitre pour vous aider en cas de blocage. Vous pouvez donc utiliser ce livre en toute autonomie pour apprendre la Statistique avec Python.

A travers ce livre, vous apprendrez à :

✅ Calculer des mesures de tendance centrale et des mesures de dispersion afin de décrire les données ;

✅ créer et interpréter des graphiques de visualisation des données en utilisant Python ainsi que les librairies Matplotlib et Seaborn ;

✅ effectuer des analyses multivariées afin d’examiner les relations existant entre plusieurs variables ;

✅ penser de manière probabiliste afin de réaliser des inférences statistiques pour tirer des conclusions à partir d’échantillons de données ;

✅ simuler des données afin d’estimer la probabilité d’un événement ;

✅ rééchantilloner les données à l’aide de techniques comme le Bootstrapping et visualiser les échantillons bootstrap ;

✅ calculer les intervalles de confiance des statistiques récapitulatives d’une population ;

✅ identifier, effectuer et interpréter les tests d’hypothèse appropriés à utiliser pour les ensembles de données ;

✅ appliquer des techniques de modélisation statistique aux données (régression linéaire et régression logistique) ;

✅ interpréter les résultats d’une modélisation statistique et évaluer la qualité des modèles ;

✅ comprendre l’apprentissage automatique ainsi que ses différences avec la modélisation statistique ;- construire et évaluer des modèles de Machine Learning (classification et régression).

Savoir programmer avec le langage Python appliqué à l’analyse des données: Cours, Exercices corrigés et Projets réels

Broché : 101 pages ISBN-13 : 979-8664840995

Un livre génial destiné aux personnes désireuses d’apprendre à programmer. Même si vous n’aviez jamais écrit auparavant une seule ligne de code, grâce à sa syntaxe intuitive et très facile à comprendre, Python vous fera entrer dans le monde passionnant de la programmation informatique appliquée à la Science des données (Data Science) qui offre d’immenses opportunités.

Avec plus de 15 ans d’expérience en programmation informatique, je vous guiderai pas à pas à travers mes explications simples, précises et efficaces pour vous permettre d’acquérir les fondamentaux du langage Python. Chaque notion est expliquée par une activité résolue puis il y a un exercice d’application pour vous permettre de pratiquer au fur et à mesure. Tous les exercices d’application sont entièrement corrigés avec les codes complets et les commentaires dans le but de vous aider à apprendre efficacement et en toute autonomie.

A travers ce livre, vous apprendrez à :

✅ configurer votre environnement Python pour un travail efficace ;

✅ écrire du code propre et concis avec Python 3 incluant des structures conditionnelles et des boucles ;

✅ écrire des programmes Python qui interagissent avec les utilisateurs et traite leurs entrées afin de générer les sorties souhaitées ;

✅ automatiser des tâches en écrivant des fonctions ;

✅ utiliser certains outils modernes comme les fonctions lambda, les listes de compréhension, les fonctions map() et filter() ;

✅ stocker l’information dans des structures de données et générer des statistiques ;

✅ effectuer une analyse des données avec des fonctionnalités de Numpy et de Pandas ;

✅ analyser de réels jeux de données.

Analyse financière et Gestion des Risques avec Python: Application à la création et l’optimisation des Portefeuilles d’Actions

Broché : 103 pages ISBN-13 : 979-8567677681

Le monde de la Finance en général et le secteur de la Bourse en particulier ont connu une révolution depuis quelques années grâce à l’apport de l’Intelligence Artificielle et à l’utilisation d’outils puissants et performants. Python a été largement adopté aussi bien par les professionnels des marchés boursiers qui l’utilisent dans leurs tâches quotidiennes que par les chercheurs, étudiants ou autres personnes intéressées par la Bourse.

Ce livre est une introduction à l’analyse technique et quantitative avec Python dans le secteur boursier.

A travers ce livre, vous apprendrez à :

✅ Importer automatiquement des données boursières à partir du Web et à les stocker en tant que dataframe ;

✅ Traiter et nettoyer des données financières (Séries Temporelles) ;✅

Créer et analyser des graphiques interactifs avec la librairie Plotly ;✅Calculer les rendements des titres (actions et du marché ;

✅Analyser statistiquement les rendements des actions ;✅

✅ Calculer de diverses manières le Risque d’un investissement financier (Volatilité Standard, VaR, CVaR, Matrice de Covariance, etc.) ;

✅Calculer des rendements ajustés au Risque (Ratio de Sharpe, Ratio de Sortino, etc.) ;✅

Effectuer des simulations Monte-Carlo pour l’estimation du Risque ;

✅Modéliser les facteurs influençant les rendements des actions afin de calculer les paramètres Alpha et Bêta ;

✅Calculer le rendement attendu d’un investissement (Action ou Portefeuille) en utilisant le modèle d’évaluation des actifs financiers (Capital Asset Pricing Model ou CAPM en Anglais) ;

✅Créer et Analyser différents types de Portefeuilles d’Actions ;✅

Générer automatiquement le rapport complet d’analyse de performance d’un portefeuille en utilisant l’outil Pyfolio ;

✅Utiliser la théorie d’Harry Markowitz pour le calcul de Portefeuille optimal ;✅

Générer de milliers de Portefeuilles avec la méthode Monte-Carlo et Sélectionner le Portefeuille à ratio de Sharpe maximum et le Portefeuille à volatilité minimale ;

✅Optimiser un Portefeuille en utilisant l’outil PyPortfolioOpt de la société Quantopian ;✅

Modéliser les cours des actions en vue de la prédiction de futurs prix grâce à de ‘simples techniques’ comme l’estimation par la moyenne, la moyenne mobile, les lissages exponentiels simple, double et triple.Les Chapitres :

✅ CHAPITRE 1 : GENERALITES ET DEFINITIONSDans ce chapitre, je vous explique ce qu’est une série temporelle et pourquoi il est très important de savoir manipuler ce type de données. Ensuite je vous explique quelques notions sur le marché boursier, les tendances en matière d’analyses de données dans ce secteur ainsi que les composantes d’une bonne analyse des données boursières.

✅CHAPITRE 2 : IMPORTATION ET ANALYSE EXPLORATOIRE DES DONNÉESDans ce chapitre, vous apprendrez comment collecter automatiquement de données boursières sur des plateformes comme Yahoo Finance sans quitter un instant votre notebook. Nous ferons le traitement et le nettoyage de ces données pour les mettre dans une forme qui facilitera nos futures analyses. Nous finirons par une analyse exploratoire des données pour mieux les comprendre.

✅CHAPITRE 3 : RENDEMENTS ET RISQUESDans ce chapitre, vous apprendrez des concepts tels les rendements, les risques, le ratio de Sharpe, le ratio de Sortino, CAPM (Capital Asset Price Management), etc. et comment les calculer. Par ailleurs, vous apprendrez à écrire des fonctions afin de mieux structurer votre code.

✅ CHAPITRE 4 : CRÉATION, ANALYSE ET OPTIMISATION D’UN PORTEFEUILLE D’ACTIONS DANS PYTHONIci, Vous apprendrez à créer différents types de portefeuilles. Vous apprendrez aussi comment optimiser un portefeuille en trouvant des pondérations risque-rendement qui sont optimales.

✅ CHAPITRE 5 : MODÈLES SIMPLESIci, vous apprendrez comment modéliser les prix des actions en utilisant l’estimation par la moyenne, les moyennes mobiles et différents types de lissages exponentiels.

Machine Learning par la pratique avec Python: Projets réels dans les Finances, l’Immobilier, le Trading, la Santé, le Marketing, etc.

Broché : 230 pages ISBN-13 : 979-8671731064

L’apprentissage automatique (Machine Learning en anglais) est un domaine de l’Intelligence artificielle qui se fonde sur des approches mathématiques et statistiques pour donner aux ordinateurs la capacité d’ apprendre à partir de données, c’est-à-dire d’améliorer leurs performances à résoudre des tâches sans être explicitement programmés pour chacune de ces tâches. Plus largement, il concerne la conception, l’analyse, l’optimisation, le développement et l’implémentation de telles méthodes.

Ce livre est purement pratique afin de vous permettre d’acquérir rapidement et efficacement les compétences nécessaires pour créer des systèmes d’apprentissage automatique (Machine Learning) dans son domaine d’intervention. Les projets couvrent plusieurs domaines. Vous apprendrez à modéliser vos données avec des algorithmes de régression, de classification, de clustering, etc. De plus, vous apprendrez à évaluer les performances des modèles créés.

A travers ce livre, vous apprendrez à :

✅ Nettoyer un jeu de données et la rendre prête pour la modélisation (Traitement des valeurs manquantes, Détection et suppression des outliers, Encodage des variables catégorielles, Normalisation des données, etc.) ;

✅ Construire un modèle de classification (LogisticRegression, RandomForestClassifier, DecisionTreeClassifier, KNeighborsClassifier, etc.) et d’un modèle de régression (LinearRegression, RandomForestRegressor, DecisionTreeRegressor, KNeighborsRegressor, etc.) ;

✅ Evaluer la performance d’un modèle (Données d’entraînement et d’évaluation, Choix de la métrique, Validation croisée, Robustesse du modèle, etc.)

✅ effectuer des prédictions ;

✅ modéliser des séries temporelles et effectuer des prévisions ;

✅ rechercher les hyperparamètres optimaux d’un modèle en utilisant les méthodes Grid Search et Random Search ;

✅ automatiser la sélection du meilleur modèle avec l’outil TPOT ;

✅ automatiser le flux de travail de vos projets de Machine Learning ;

✅ effectuer des segmentations avec des algorithmes comme KMeans ;

✅ réduire la dimension de grand ensembles de données en utilisant l’ACP, …etc.

APPRENDRE À PROGRAMMER AVEC R ET RSTUDIO: MANUEL DE COURS ET EXERCICES CORRIGÉS POUR DÉBUTANTS

Broché : 226 pages ISBN-13 : 979-8790793295

R est l’un des langages informatiques les plus utilisés. Plus qu’un langage, R est un environnement intégré et complet pour la conception, la réalisation et la vulgarisation d’un projet concernant l’analyse des données. R peut être utilisé pour des tâches telles que la modélisation statistique, la visualisation des données, l’apprentissage automatique (Machine Learning), l’analyse des séries temporelles, les études économétriques, l’analyse quantitative, le traitement des données textuelles, etc.

A travers ce livre, vous apprendrez à :

✅ nstaller et Configurer votre environnement de travail pour pouvoir écrire du code R ;

✅ écrire votre premier programme (‘Hello World’) et effectuer des opérations basiques (Addition, Soustraction, Multipication, Division, Exponentiel, Modulo, etc.) ;

✅ afficher les résultats d’un code en utilisant de différentes manières les fonctions print(), paste() et cat() ;

✅ créer des variables et à les réutiliser ;

✅ manipuler différents types de données tels que les entiers naturels, les booléens, les chaînes de caractères, les nombres décimaux, les matrices, les vecteurs, les listes, les dataframes, etc.

✅ créer une dataframe et recueillir des informations concernant sa structure et son résumé statistique ;

✅ combiner des booléens, des opérateurs logiques et des opérateurs de comparaison ;

✅ écrire du code propre et concis incluant des structures conditionnelles if, if…else, if…else if…else, des boucles for et while ;

✅ utiliser les fonctions de la famille apply tels que lapply(), sapply() et vapply() ;

✅ créer vos propres fonctions et les optimiser afin d’automatiser certaines tâches et rendre votre code réutilisable ;

✅ créer des listes de compréhension vous permettant d’écrire des boucles for plus ou moins complexes en une seule ligne de code ;

✅ importer différents types de fichiers tels que Excel, CSV, txt, TSV, …;

✅ importer des données provenant du web à partir des API (Application Programing Interface) et du WebScraping ;

✅ manipuler les données à la manière de Tidyverse avec les fonctions filter(), arrange(), mutate(), select(), summarise() et group_by() ;

✅ créer des graphiques tels que les nuages de points (avec droite de régression), les diagrammes à barres, les courbes, les histogrammes, les boîtes à moustache ainsi que des subplots (sous-graphiques) ;

✅ traiter les variables catégorielles en utilisant les fonctionnalités de la librairie forcats ;

✅ effectuer des jointures de tables (jointure interne, à gauche, à droite, complète ainsi qu’une semi-jointure et une anti-jointure) avec la librairie dplyr.

Ce livre est également disponible en version PDF : https://buy.stripe.com/aEU7wu1kW4EG94A6ov

Mes livres sont disponibles en vente sur Amazon aussi en versions papier (broché) et numérique (kindle) : https://www.amazon.fr/Josu%C3%A9-AFOUDA/e/B08F17S1V8/ref=dp_byline_cont_pop_book_1

N’oublier pas lorsque vous acheter un de mes livres de laisser un petit commentaire et aussi 5 étoiles :) sur le site d’achat. Ceci est vraiment encourageant pour continuer cette mission de démocratisation de la connaissance en Science des données. Merci.

Voici d’autres formations qui vous aideront à vous perfectionner et à acquérir de nouvelles compétences :

Profitez également de nos vidéos tutoriels sur la chaîne YouTube JA DATATECH CONSULTING. Abonnez-vous pour ne rien rater.