Assez récemment, au cours d’une séance de coaching, une des mes clientes m’a montré des analyses exploratoires de son jeu de données, qu’elle avait réalisé avec le package DataExplorer
. Comme les analyses étaient intéressantes et que ce n’était pas la première fois que j’entendais parler de ce package, j’ai décidé de le “décortiquer”.
Dans cet article, je vous montre, en pas à pas, les fonctions qui ont retenu mon attention. Et en guise de conclusion, je vous donnerai mon avis global sur ce package DataExplorer.
Les analyses exploratoires – ou EDA en anglais pour Explanatory Data Analysis- servent à faire un état des lieux des données : Quelles sont les dimensions (nombre de lignes, nombre de colonnes) du data frame ? Quel est le pourcentage de données manquantes, où sont elles ? Quelles sont les variables quantitatives et quelles sont les variables qualitatives. Quelles sont les distributions des variables ? Quelles sont, grossièrement, les relations entre les variables ? Etc…
Je dirais que les analyses exploratoires interviennent immédiatement après le nettoyage des données, et juste avant les analyses descriptives, qui sont plus précises que les analyses exploratoires, et qui vont s’intéresser plus particulièrement à certaines variables.
Ce package est disponible sur CRAN, il est donc facile à installer à partir de RStudio:
#install.packages("DataExplorer")
library("DataExplorer")
La promesse de DataExplorer
c’est d’automatiser l’exploration des variables (dimension, données manquantes, distribution, corrélation etc) d’un data frame, pour nous permettre de nous concentrer sur la compréhension des données.
Sur le principe, c’est super intéressant, parce que l’exploration des données c’est chronophage, et on ne peut pas trop s’en passer pour bien comprendre le jeu de données !
DataExplorer
contient une vingtaine de fonctions. Je les ai essayé de manière systématique, les une après les autres, en employant le jeu de données heart_disease
du package funModeling parce que je le connais bien (et vous aussi si vous suivez mes articles ) 😉
#install.packages("funModeling")
library("funModeling")
Pour cette première étape, trois fonctions ont retenu mon attention, introduce()
, plot_intro()
et plot_str()
. Elles permettent toutes les trois d’obtenir des informations sur la structure de données, c’est-à-dire leurs dimensions, les class (ou types de variables), la présence de données manquantes, etc.
introduce(heart_disease)
## rows columns discrete_columns continuous_columns all_missing_columns
## 1 303 16 7 9 0
## total_missing_values complete_rows total_observations memory_usage
## 1 6 297 4848 28800
Cette fonction permet d’obtenir les mêmes informations, mais sous la forme d’un graphique :
plot_intro(heart_disease)
Cette fonction permet d’aller dans le détail de chaque variable et d’obtenir un résultat synthétique, sous la forme d’un graphique (au format html).
Suite à l’exploration de la structure des données, il est parfois nécessaire de modifier la class de certaines variables. Par exemple, pour passer une variable de type chaîne de caractères vers une variable de type factor, ou inversement.
Le package DataExplorer
dispose d’une fonction très utile pour cela, la fonction update_columns
. Cette fonction permet de modifier le type d’une ou plusieurs variables en une seule ligne de commande, en utilisant les noms ou les indices (position de la variable).
Par exemple, la variable age est de class integer. Si je voulais le changer en chaîne de caractères (character) :
# copie de heart_disease
HD <- heart_disease
class(heart_disease$age) #integer
## [1] "integer"
HD <- update_columns(HD, "age", as.character)
class(HD$age)# character
## [1] "character"
Un autre exemple, avec plusieurs variables :
class(HD$resting_blood_pressure) #integer
## [1] "integer"
class(HD$serum_cholestoral) #integer
## [1] "integer"
# avec plusieurs variables, en utilisant les noms
HD <- update_columns(HD, c("resting_blood_pressure","serum_cholestoral"), as.numeric)
class(HD$resting_blood_pressure) #numeric
## [1] "numeric"
class(HD$serum_cholestoral) #numeric
## [1] "numeric"
Idem, en utilisant des indices :
str(HD[,2:5])
## 'data.frame': 303 obs. of 4 variables:
## $ gender : Factor w/ 2 levels "female","male": 2 2 2 2 1 2 1 1 2 2 ...
## $ chest_pain : Factor w/ 4 levels "1","2","3","4": 1 4 4 3 2 2 4 4 4 4 ...
## $ resting_blood_pressure: num 145 160 120 130 130 120 140 120 130 140 ...
## $ serum_cholestoral : num 233 286 229 250 204 236 268 354 254 203 ...
HD <- update_columns(heart_disease, 2:5, as.character)
str(HD[,2:5])
## 'data.frame': 303 obs. of 4 variables:
## $ gender : chr "male" "male" "male" "male" ...
## $ chest_pain : chr "1" "4" "4" "3" ...
## $ resting_blood_pressure: chr "145" "160" "120" "130" ...
## $ serum_cholestoral : chr "233" "286" "229" "250" ...
Les données manquantes c’est toujours embêtant, à minima parce que, par défaut, R ne les gère pas. Il faut souvent utiliser l’argument na.rm=TRUE
dans les fonctions descriptives, par exemple. Et puis aussi parce que certaines approches statistiques ne les tolèrent pas, comme l’ACP par exemple. C’est donc bien de réaliser une exploration des données manquantes pour se faire une idée de leur nombre et de leur répartition.
Pour cela le package propose deux fonctions : plot_missing()
et profiling_missing()
.
Cette fonction permet d’obtenir, sous la forme d’un graphique, le pourcentage de données manquante pour chaque variables. C’est plutôt simple et efficace :
plot_missing(heart_disease)
Remarque : pour aller plus loin dans l’exploration visuelle de la distribution des données manquantes, vous pouvez aussi consulter cet article “Visualisation des données manquantes“, et aussi employer la fonction aggr()
du package VIM.
La fonction profiling_missing()
permet d’obtenir les pourcentages et les effectifs correspondants de données manquantes, mais sous la forme d’un data frame:
profile_missing(heart_disease)
## feature num_missing pct_missing
## 1 age 0 0.00000000
## 2 gender 0 0.00000000
## 3 chest_pain 0 0.00000000
## 4 resting_blood_pressure 0 0.00000000
## 5 serum_cholestoral 0 0.00000000
## 6 fasting_blood_sugar 0 0.00000000
## 7 resting_electro 0 0.00000000
## 8 max_heart_rate 0 0.00000000
## 9 exer_angina 0 0.00000000
## 10 oldpeak 0 0.00000000
## 11 slope 0 0.00000000
## 12 num_vessels_flour 4 0.01320132
## 13 thal 2 0.00660066
## 14 heart_disease_severity 0 0.00000000
## 15 exter_angina 0 0.00000000
## 16 has_heart_disease 0 0.00000000
Après l’étude de la structure et des données manquantes, on peut s’intéresser à la distribution des variables. Les graphiques permettent une synthèse optimale de l’information.
Pour explorer les variables qualitatives, le package DataExplorer
propose la fonction plot_bar()
.
Les distributions peuvent être obtenues de façon globale, ou par sous-groupes:
# global
plot_bar(heart_disease)
# par sous-groupes
plot_bar(heart_disease, by ="gender")
Les graphs peuvent être améliorés, vous trouverez plus d’information dans la page d’aide des fonctions. Par exemple :
?plot_bar()
De façon analogue, pour les variables quantitatives, le package propose les fonctions plot_histogram()
et plot_qq()
. Ces fonctions sont plutôt pratiques pour visualiser les distributions et se faire une première idée quant à la normalité ou non des variables :
plot_histogram(heart_disease)
plot_qq(heart_disease)
Les qqplot peuvent être obtenus en distinguant des sous-groupes :
plot_qq(heart_disease, by="chest_pain")
Les relations entre les variables peuvent également être explorées à l’aide de graphiques, générés notamment par les fonctions plot_correlation()
, plot_prcomp()
, plot_boxplot()
et plot_scatterplot()
La fonction plot_correlation
permet d’obtenir une matrice de corrélation visuelle pour l’ensemble des variables (quantitatives ou qualitatives). Obtenir une matrice de corrélation sur des variables qualitatives peut paraître un peu surprenant… Pour cela des variables indicatrices, ou “dummy” variables (comportant des 0 et des 1) sont créées et les corrélations sont calculées à partir de ces données numériques.
Le package comporte d’ailleurs une fonction (dummify()
– très intéressante !) pour créer ces dummy variables. Mais ici la fonction plot_correlation
le fait de toute seule.
plot_correlation(heart_disease, cor_args = list("use" = "pairwise.complete.obs"))
On peut aussi obtenir une matrice des corrélations, uniquement pour les variables qualitatives et uniquement avec les variables quantitatives. Pour cela, on ajoute l’argument type="d"
pour les données discrètes (catégorielles) et type="c"
pour les données continues (quantitatives)
plot_correlation(heart_disease, cor_args = list("use" = "pairwise.complete.obs"), type="d")
plot_correlation(heart_disease, cor_args = list("use" = "pairwise.complete.obs"), type="c")
Remarque : Pour obtenir des informations complémentaires sur les matrices de corrélation, vous pouvez consulter cet article “Correlations deux à deux”.
Les corrélations peuvent aussi s’apprécier par les sorties de la fonction plot_prcomp()
, qui réalise une ACP (analyse en composantes principale). Les infos sur les pourcentages d’inertie nous permettent d’apprécier sur combien de dimensions les données peuvent être réduites.
plot_prcomp(na.omit(heart_disease), nrow = 2L, ncol = 2L)
Remarques : vous pourrez trouver davantage d’informations sur l’approche ACP dans l’article “Ressources pour l’ACP“.
La fonction plot_boxplot()
permet de visualiser ces relations en créant des boxplots pour toutes les variables numériques, en une seule ligne de commande. La variable catégorielle est spécifiée à l’aide de l’argument by
.
plot_boxplot(heart_disease, by="gender")
Les boxplots sont simples (les observations ne sont superposées) mais pour de l’exploration cela me semble suffisant.
Pour cela, nous pouvons employer la fonction plot_scatterplot()
, mais il est nécessaire, soit en amont, soit dans la fonction, de sélectionner uniquement les variables quantitatives (ici dans la fonction, avec la commande split_columns(heart_disease)$continuous
).
plot_scatterplot(split_columns(heart_disease)$continuous, by = "max_heart_rate")
Il est même possible de réaliser un échantillonnage lorsque les données sont très nombreuses, en utilisant l’argument sampled_rows
.
Lepackage DataExplorer
propose la fonction dummify()
pour créer des variables indicatrices (ou dummy variables) à partir d’une variable catégorielle. Voici un exemple :
library(tidyverse)
# subset avec 3 variables catégorielle
HD_simple <- heart_disease %>%
select(gender, chest_pain, has_heart_disease)
str(HD_simple)
## 'data.frame': 303 obs. of 3 variables:
## $ gender : Factor w/ 2 levels "female","male": 2 2 2 2 1 2 1 1 2 2 ...
## $ chest_pain : Factor w/ 4 levels "1","2","3","4": 1 4 4 3 2 2 4 4 4 4 ...
## $ has_heart_disease: Factor w/ 2 levels "no","yes": 1 2 2 1 1 1 2 1 2 2 ...
HD_simple2 <- dummify(HD_simple)
str(HD_simple2)
## 'data.frame': 303 obs. of 8 variables:
## $ gender_female : int 0 0 0 0 1 0 1 1 0 0 ...
## $ gender_male : int 1 1 1 1 0 1 0 0 1 1 ...
## $ chest_pain_1 : int 1 0 0 0 0 0 0 0 0 0 ...
## $ chest_pain_2 : int 0 0 0 0 1 1 0 0 0 0 ...
## $ chest_pain_3 : int 0 0 0 1 0 0 0 0 0 0 ...
## $ chest_pain_4 : int 0 1 1 0 0 0 1 1 1 1 ...
## $ has_heart_disease_no : int 1 0 0 1 1 1 0 1 0 0 ...
## $ has_heart_disease_yes: int 0 1 1 0 0 0 1 0 1 1 ...
## - attr(*, ".internal.selfref")=<externalptr>
Bon ben ça, c’est pas la cerise sur le gâteau, c’est le gâteau tout entier !
Toutes les fonctions que l’on vient de voir (et d’autres), peuvent être appliquées automatiquement sur votre jeu de données, avec une seule ligne de commande. Et vous pouvez obtenir les résultats dans un fichier html, tout beau tout propre ! Ca paraît trop beau ? C’est pourtant vrai. La fonction à employer est create_repor()
, comme cela :
create_report(heart_disease)
Vous pouvez choisir les analyses réalisées dans ce rapport, en employant la fonction configure_report
.
configure_report(
add_introduce = TRUE,
add_plot_intro = TRUE,
add_plot_str = TRUE,
add_plot_missing = TRUE,
add_plot_histogram = TRUE,
add_plot_density = FALSE,
add_plot_qq = TRUE,
add_plot_bar = TRUE,
add_plot_correlation = TRUE,
add_plot_prcomp = TRUE,
add_plot_boxplot = TRUE,
add_plot_scatterplot = TRUE,
introduce_args = list(),
plot_intro_args = list(),
plot_str_args = list(type = "diagonal", fontSize = 35, width = 1000, margin =
list(left = 350, right = 250)),
plot_missing_args = list(),
plot_histogram_args = list(),
plot_density_args = list(),
plot_qq_args = list(sampled_rows = 1000L),
plot_bar_args = list(),
plot_correlation_args = list(cor_args = list(use = "pairwise.complete.obs")),
plot_prcomp_args = list(),
plot_boxplot_args = list(),
plot_scatterplot_args = list(sampled_rows = 1000L),
global_ggtheme = quote(theme_gray()),
global_theme_config = list()
)
En principe, il doit être possible de générer le rapport en docx ou .pdf, mais je ne suis pas parvenue à changer le format de sortie par défaut (html).
Après cette exploration du package, je suis plutôt séduite. Non seulement le package facilite la réalisation des analyses exploratoires, mais il les rend aussi très intelligibles par l’emploi de graphiques, et surtout il les automatise !
Et ça, c’est un gain de temps considérable. Et puis le package est très facile d’utilisation.
En rentant davantage dans le détail des fonctions, j’ai bien apprécié les fonctions la réalisation de matrice de corrélation avec les variables catégorielles, et la restitution très simple de l’ACP.
Cette étude du package DataExplorer
me donne envie de décortiquer d’autres packages dédiés à l’exploration des données.
J’aimerais bien, ensuite, faire un récapitulatif pour décrire quelle fonction de quel package permet de faire facilement telle ou telle étape de l’analyse exploratoire. Est-ce que ça vous intéresse ? Dites-le-moi en commentaire !
Et si vous souhaitez me suggérer des packages à étudier n’hésitez pas non plus !
Si cet article vous a plu, ou vous a été utile vous pouvez soutenir le blog, en réalisant un don libre sur sa page Tipeee.
Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.
29 Responses
Bonjour, j’espère que vous allez bien ? Est-il possible d’obtenir les graphes en français ?
Bonjour, je ne pense pas, mais je n’ai pas essayé…
Bonjour !
Merci pour cet article très clair ( comme d’habitude 🙂 ) sur ce package que je ne connaissais pas.
Votre proposition d’approfondir sur les analyses exploratoires est intéressante !
Bonne journée !
très intéressant , merci
Merci beaucoup pour ce partage! Votre blog est toujours une mine d’informations précieuses.
L’idée d’une compilation des packages dediés à l’exploration des données est top. J’attends cet article avec impatience
Hello bonjour,
Personnellement je commence en Data analyse et je dois admettre avoir un penchant pour R. Cet article est très intéressant et je vous en remercie. Effectivement je vais tenter d’utiliser ce package dans un projet de ma formation pour essayer de mettre en évidence des corrélations.
Grand Merci dans tous les cas car ce fut une belle surprise de voir ce mail d’info aujourd’hui ! C’est un peu Noël presque tous les jours avec Della data !
Bonne semaine !
L.
Dear Della,
Cet article m’a beaucoup plus et vient de repondre à une de mes préoccupations surtout sur les corrélations avec les variables catégorielles et bien d’autres aussi. Merci beaucoup
Formidable et très pratique!Merci pour le partage.
Merci Claire pour la découverte de ce package intéressant présenté en outre de façon claire ( 🙂 ) et efficace
Bonjour,
Article intéressant.
Merci
Salut !
Merci pour cet excellent article et surtout pour ce package trèèèès intéressant. Je m’en vais l’essayer tout de suite !
En revanche, je n’ai pas bien compris la fonction plot_str()…. A quoi sert-elle exactement ?
Elle fournit un plot avec une description de la structure des données. C’est l’équivalent de la fonction str, mais sous une forme graphique.
Super intéressant ! Et ça va m’être très pratique et me faciliter ce travail !
Merci Claire !
Très interessant chère Della, continue à nous formés en ligne en exploitant d’autre package pour plus d’information.
Très respectueusement , je vous fournis les arguments principaux qui me font critiquer très négativement l’outil proposé dans le cadre où vous le présentez
.
1) Notre cerveau est ainsi conçu qu’il recherche la facilité , ce qui est utile pour un mammifère en milieu hostile mais pas dans la recherche;
la conséquence en est qu’il se laisse fasciner par la première forme qu’il reconnaît dans son catalogue d’expériences : il va développer une cécité spécifique à tout autre signe qui mettrait en péril la valeur de cette forme identifiée.
Ne perdons pas de vue le stress lié à toute recherche qui en rajoute une couche.
2) Le paradigme de toutes les recherches du XXI ème siècle est essentiellement basé sur la complexité , et nous savons que l’identification d’une “Solution magique ???” amènerait immédiatement à une simplification catastrophique des raisonnements et surtout de nos représentations.
3) Le plus mauvais moment pour le parasitage de la démarche est vraiment au début de la recherche ; en effet c’est le moment pour douter de tout et de ses “contraires” : c’est le moment de s’ouvrir à la réalité et de s’interdire toute conclusion hâtive , c’est le moment du rêve éveillé.
4) Le calcul n’est jamais qu’un calcul , quelle que soit l’élégance de sa ou ses forme(s) c’est le chercheur qui doit s’il le peut lui donner un sens …
J’ose : ” Science sans conscience , n’est que ruine de l’âme ( Vous savez qui) ”
Par contre : je recommande l’usage de ce genre d’outils une fois le modèle bien établi pour examiner : soit à quels pièges vous avez échappé soit que vous êtes passé à côté de la question et qu’il tout recommencer …
Très cordialement.
Paradoxalix
<> est un projet dont la realisation va me faire du bien !
Merci d’avance.
Merci beaucoup cher Della. Je crois que je suis satisfait. Thank you very much for this documents.
Best regards.
Adjobi Claver.
Absolument Genial!!!! Merci infiniment …quoiqu’en pense Paradoxalix
Waouh, très génial le package. Merci infiniment pour ce sens de partage.
Bonne continuation
Très émerveillé Claire ! Merci à toi
Merci beaucoup!!!!!
Bonjour Della très gentile de votre par cet article me fera beaucoup de bien dans mais prochaines analyses.
j’aimerais vous demander si cela est possible bien d’avoir un article qui traite de l’apurement des données?
Très cordialement à vous
Une très belle découverte. Au contraire de ce que certains peuvent en dire, je ne pense pas que cet outil soit un prétexte à l’absence de calcul réalisé par nos soins ou l’absence de réflexion préalable à notre jeu de données, mais c’est surtout un moyen d’aider des personnes pour lesquelles les commandes dans R restent encore un peu obscures. Nous pouvons très bien comprendre ce que chaque graphique automatiquement généré illustre et vérifier par nous-même ensuite de potentielles erreurs par rapport à nos résultats, mais c’est une réelle aide pour sonder un jeu de données rapidement et sans frustration de se tromper dans les codes de R.
Merci pour vos articles, de précieuses pépites dans le cadre de mes analyses en écologie. 🙂
Bonjour Della,
Votre article est très riche. Grand merci à vous.
Est-ce possible de réaliser un article qui porte sur l’apurement des données?
Merci bien
Bonjour,
ce n’est pas dans ma liste actuellement, car c’est un sujet que je ne connais pas très bien.
Super merci beaucoup pour la découverte
Très intéressant, merci!
très ravis.
en un mot, MERCI
merci Claire, c’est trés interessant