flowchart LR
A[Nettoyage] --> B[Exploration]
B --> C{Analyse}
9 Nettoyage (a)
9.1 Données binaires
Jusqu’ici, on a exploré des variables continues (temps de réaction, note, etc.) ainsi que des variables catégorielles (p. ex., ville). Cependant, notre variable de réponse était toujours continue. Dans la deuxième partie du cours, on examine les variables de réponse binaire, c’est-à-dire les variables telles que « correct/incorrect », « oui/non », etc. Ce type de variable est très commun dans la recherche en linguistique, mais on verra que les méthodes de visualisation ainsi que d’analyse statistique utilisée sont distinctes.
9.1.1 Une situation plus réaliste
Bien que les données examinées jusqu’ici soient généralement propres et organisées, la situation réaliste de l’analyste est rarement aussi simple. Pour commencer notre exploration des données binaires, on utilisera des données plus réalistes à partir d’un questionnaire élaboré sur MS Forms. On a vu en classe que les données générées par ce type de plateforme sont souvent chaotiques. Donc, il a fallu les nettoyer avant d’être capable d’explorer ou d’analyser les patrons d’intérêt. Le nettoyage des données était notre objectif en classe. Bref, pour nettoyer nos données, on peut utiliser une combinaison d’outils :
- L’extension
janitorpour simplifier et standardiser les noms des variables/colonnes - La fonction
pivot_longer(), déjà utilisée dans la première partie du cours, pour transformer nos données - La fonction
rename()pour renommer des variables selon le besoin - Les fonctions
select()etfilter(), déjà utilisées dans le cours, selon le besoin
9.2 Une structure de travail organisée
Pour éviter des scripts qui sont trop longs (et qui seront normalement moins organisés), on peut diviser notre travail dans une séquence d’étapes. Par exemple, on utilise un script pour charger les extensions, pour importer nos données et pour les nettoyer. Ensuite, on utilise un autre script pour explorer les patrons pertinents. Finalement, un troisième script contiendra l’analyse statistique.
Chaque script qui dépend du script précédent contiendra la ligne source(...) pour « charger » le script nécessaire. On verra bientôt comment enchaîner nos scripts avec cette fonction-là. Pour l’instant, on utilise un seul script, vu qu’on travaille sur le nettoyage des données. Le script en question s’appellera script_10_net.R (choisissez un nom logique pour votre script).
9.3 Notre script + nettoyage de données
Le script utilisé en classe, script_10_net.R est commenté ci-dessous — il faudra installer1 l’extension janitor (suivez le modèle ci-dessous).
Code
# Charger les extensions :
library(tidyverse)
# install.packages(janitor)
library(janitor)
# Importer les données :
q = read_csv2("donnees/supplementaires/questionnaire.csv")Si vous visualisez les données avec glimpse(d), vous verrez que le fichier n’est pas tidy : il y a plusieurs colonnes qui ne sont pas nécessaires. En plus, les questions sont distribuées à travers les colonnes, et les noms des colonnes sont immenses. Simplement dit, le fichier est chaotique.
9.3.1 Standardisation des noms
Il faut simplifier et standardiser les noms des colonnes. Idéalement, on ne veut pas avoir des espaces dans les noms des variables (c’est pourquoi on voit plusieurs accents graves dans les noms de colonnes maintenant). La fonction clean_names() de l’extension janitor sera très utile ici :
Code
q = clean_names(q) # Remplacer la version originale par la version simplifiée/standardisée
glimpse(q)
#> Rows: 18
#> Columns: 50
#> $ id <dbl> …
#> $ heure_de_debut <chr> …
#> $ heure_de_fin <chr> …
#> $ adresse_de_messagerie <chr> …
#> $ nom <lgl> …
#> $ total_points <lgl> …
#> $ quiz_feedback <lgl> …
#> $ heure_de_la_derniere_modification <lgl> …
#> $ votre_nom <chr> …
#> $ points_votre_nom <lgl> …
#> $ feedback_votre_nom <lgl> …
#> $ votre_date_de_naissance <chr> …
#> $ points_votre_date_de_naissance <lgl> …
#> $ feedback_votre_date_de_naissance <lgl> …
#> $ combien_de_langues_parlez_vous <dbl> …
#> $ points_combien_de_langues_parlez_vous <lgl> …
#> $ feedback_combien_de_langues_parlez_vous <lgl> …
#> $ avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique <chr> …
#> $ points_avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique <lgl> …
#> $ feedback_avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique <lgl> …
#> $ est_ce_que_toutes_les_langues_utilisent_des_voyelles_dans_leur_systeme_phonetique <chr> …
#> $ points_est_ce_que_toutes_les_langues_utilisent_des_voyelles_dans_leur_systeme_phonetique <lgl> …
#> $ feedback_est_ce_que_toutes_les_langues_utilisent_des_voyelles_dans_leur_systeme_phonetique <lgl> …
#> $ le_francais_est_il_la_seule_langue_avec_des_voyelles_nasales <chr> …
#> $ points_le_francais_est_il_la_seule_langue_avec_des_voyelles_nasales <lgl> …
#> $ feedback_le_francais_est_il_la_seule_langue_avec_des_voyelles_nasales <lgl> …
#> $ est_ce_que_certaines_langues_ont_plus_de_consonnes_que_de_voyelles <chr> …
#> $ points_est_ce_que_certaines_langues_ont_plus_de_consonnes_que_de_voyelles <lgl> …
#> $ feedback_est_ce_que_certaines_langues_ont_plus_de_consonnes_que_de_voyelles <lgl> …
#> $ toutes_les_langues_ont_elles_des_consonnes_plosives_comme_le_p_et_le_b <chr> …
#> $ points_toutes_les_langues_ont_elles_des_consonnes_plosives_comme_le_p_et_le_b <lgl> …
#> $ feedback_toutes_les_langues_ont_elles_des_consonnes_plosives_comme_le_p_et_le_b <lgl> …
#> $ existe_t_il_des_langues_qui_n_utilisent_pas_le_son_l <chr> …
#> $ points_existe_t_il_des_langues_qui_n_utilisent_pas_le_son_l <lgl> …
#> $ feedback_existe_t_il_des_langues_qui_n_utilisent_pas_le_son_l <lgl> …
#> $ le_r_francais_comme_dans_rouge_se_retrouve_t_il_dans_toutes_les_langues <chr> …
#> $ points_le_r_francais_comme_dans_rouge_se_retrouve_t_il_dans_toutes_les_langues <lgl> …
#> $ feedback_le_r_francais_comme_dans_rouge_se_retrouve_t_il_dans_toutes_les_langues <lgl> …
#> $ y_a_t_il_des_langues_sans_voyelles_arrondies <chr> …
#> $ points_y_a_t_il_des_langues_sans_voyelles_arrondies <lgl> …
#> $ feedback_y_a_t_il_des_langues_sans_voyelles_arrondies <lgl> …
#> $ le_chinois_est_il_la_seule_langue_qui_utilise_des_tons <chr> …
#> $ points_le_chinois_est_il_la_seule_langue_qui_utilise_des_tons <lgl> …
#> $ feedback_le_chinois_est_il_la_seule_langue_qui_utilise_des_tons <lgl> …
#> $ est_ce_que_toutes_les_langues_du_monde_ont_des_mots_qui_riment <chr> …
#> $ points_est_ce_que_toutes_les_langues_du_monde_ont_des_mots_qui_riment <lgl> …
#> $ feedback_est_ce_que_toutes_les_langues_du_monde_ont_des_mots_qui_riment <lgl> …
#> $ toutes_les_langues_utilisent_elles_le_son_s_comme_dans_soleil <chr> …
#> $ feedback_toutes_les_langues_utilisent_elles_le_son_s_comme_dans_soleil <lgl> …
#> $ points_toutes_les_langues_utilisent_elles_le_son_s_comme_dans_soleil <lgl> …9.3.2 Sélection des colonnes pertinentes
Ensuite, on va enlever des colonnes inutiles. Par exemple, on voit des colonnes qui commencent par « feedback_… », par « points_… », etc. Les colonnes qui commencent par « heure_… », « adresse_… », « quiz_… » ou « total_… » peuvent être enlevées aussi. Ici, on utilise la fonction select(), déjà utilisée dans le cours, ainsi que la fonction matches() pour trouver des patrons des caractères. L’accent circonflexe signifie « le début d’une séquence »; la barre verticale signifie « ou ». Donc, ici on enlève les colonnes qui contiennent les mots « heure », « adresse », « nom », « feedback », « points », « total » ou « quiz ».
Code
q = q |>
select(-matches("^(heure|adresse|nom|feedback|points|total|quiz)"))
glimpse(q, width = 50) # largeur de 50%
#> Rows: 18
#> Columns: 15
#> $ id <dbl> …
#> $ votre_nom <chr> …
#> $ votre_date_de_naissance <chr> …
#> $ combien_de_langues_parlez_vous <dbl> …
#> $ avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique <chr> …
#> $ est_ce_que_toutes_les_langues_utilisent_des_voyelles_dans_leur_systeme_phonetique <chr> …
#> $ le_francais_est_il_la_seule_langue_avec_des_voyelles_nasales <chr> …
#> $ est_ce_que_certaines_langues_ont_plus_de_consonnes_que_de_voyelles <chr> …
#> $ toutes_les_langues_ont_elles_des_consonnes_plosives_comme_le_p_et_le_b <chr> …
#> $ existe_t_il_des_langues_qui_n_utilisent_pas_le_son_l <chr> …
#> $ le_r_francais_comme_dans_rouge_se_retrouve_t_il_dans_toutes_les_langues <chr> …
#> $ y_a_t_il_des_langues_sans_voyelles_arrondies <chr> …
#> $ le_chinois_est_il_la_seule_langue_qui_utilise_des_tons <chr> …
#> $ est_ce_que_toutes_les_langues_du_monde_ont_des_mots_qui_riment <chr> …
#> $ toutes_les_langues_utilisent_elles_le_son_s_comme_dans_soleil <chr> …9.3.3 Transformation wide-to-long
On a déjà vu comment transformer les tableaux qui sont trop longs : on utilise la fonction pivot_longer(). Dans la fonction, il faut spécifier quelles colonnes seront transformées. Normalement, c’est facile de nommer ces colonnes. Le problème ici, ce sont les noms des colonnes, qui sont trop longs. Une solution est d’utiliser les indices des colonnes pertinentes (c’est-à-dire les positions des colonnes dans le tableau). Comment trouver ces indices? On utilise la fonction names(q) pour lister les noms de toutes les colonnes avec leurs indices. Cherchez la première question et remarquez son indice. Ici, les questions de notre questionnaire sont dans les colonnes 6 à 15.
Code
# Vérifions les noms des colonnes :
names(q)
#> [1] "id"
#> [2] "votre_nom"
#> [3] "votre_date_de_naissance"
#> [4] "combien_de_langues_parlez_vous"
#> [5] "avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique"
#> [6] "est_ce_que_toutes_les_langues_utilisent_des_voyelles_dans_leur_systeme_phonetique"
#> [7] "le_francais_est_il_la_seule_langue_avec_des_voyelles_nasales"
#> [8] "est_ce_que_certaines_langues_ont_plus_de_consonnes_que_de_voyelles"
#> [9] "toutes_les_langues_ont_elles_des_consonnes_plosives_comme_le_p_et_le_b"
#> [10] "existe_t_il_des_langues_qui_n_utilisent_pas_le_son_l"
#> [11] "le_r_francais_comme_dans_rouge_se_retrouve_t_il_dans_toutes_les_langues"
#> [12] "y_a_t_il_des_langues_sans_voyelles_arrondies"
#> [13] "le_chinois_est_il_la_seule_langue_qui_utilise_des_tons"
#> [14] "est_ce_que_toutes_les_langues_du_monde_ont_des_mots_qui_riment"
#> [15] "toutes_les_langues_utilisent_elles_le_son_s_comme_dans_soleil"
# Notez que les questions du questionnaire commencent dans la colonne 6 (jusqu'à la colonne 15)
# Transformation wide-to-long :
long = q |>
pivot_longer(names_to = "question",
values_to = "reponse",
cols = 6:15)
glimpse(long, width = 50)
#> Rows: 180
#> Columns: 7
#> $ id <dbl> …
#> $ votre_nom <chr> …
#> $ votre_date_de_naissance <chr> …
#> $ combien_de_langues_parlez_vous <dbl> …
#> $ avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique <chr> …
#> $ question <chr> …
#> $ reponse <chr> …9.3.4 Ajustements finaux
Finalement, notez qu’on a une colonne immense : « avez_vous_suivi_… ». C’est terrible. On va encore simplifier les noms des variables avec la fonction rename() :
Code
long = long |>
rename("nom" = "votre_nom", # on va enlever cette colonne pour garantir l'anonymat
"naissance" = "votre_date_de_naissance",
"langues" = "combien_de_langues_parlez_vous",
"phonologie" = "avez_vous_suivi_le_cours_de_phonologie_ou_de_phonetique") |>
select(-nom)
# On pourrait utiliser les indices des colonnes au lieu de leurs noms
glimpse(long, width = 50)
#> Rows: 180
#> Columns: 6
#> $ id <dbl> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,…
#> $ naissance <chr> "11-13-2023", "11-13-2023", "…
#> $ langues <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
#> $ phonologie <chr> "Oui", "Oui", "Oui", "Oui", "…
#> $ question <chr> "est_ce_que_toutes_les_langue…
#> $ reponse <chr> "Non", "Non", "Oui", "Non", "…L’avantage d’utiliser la fonction glimpse() est qu’elle nous donne la classe de chaque variable dans le tableau. Ici, on voit que la variable id est considérée comme dbl (double, c’est-à-dire numérique). C’est un problème, vu que l’identification de chaque participant représente un facteur (fct). En plus, toutes les variables chr sont, en réalité, fct aussi. Observez le code ci-dessous.
Code
long = long |>
mutate(id = as_factor(id),
across(where(is_character), as_factor))
glimpse(long, width = 50)
#> Rows: 180
#> Columns: 6
#> $ id <fct> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,…
#> $ naissance <fct> 11-13-2023, 11-13-2023, 11-13…
#> $ langues <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
#> $ phonologie <fct> Oui, Oui, Oui, Oui, Oui, Oui,…
#> $ question <fct> est_ce_que_toutes_les_langues…
#> $ reponse <fct> Non, Non, Oui, Non, Oui, Non,…La ligne across(where(is_character), as_factor) vérifie la classe de chaque variable. Si la classe est chr, on la change vers fct — n’importe combien des colonnes chr existe dans le tableau.
Pratique
Pour les questions ci-dessous, vous aurez besoin d’une clé de réponse.
Question 1. Importez et nettoyez le fichier questionnaire2.csv. N’oubliez pas d’enlever la colonne qui indique les noms des participants.
Question 2. Quel est le score de chaque participant?
Question 3. Le goût pour la géographie affecte-t-il la précision des réponses?
Question 4. Créez une figure appropriée pour les données en question.
Une fois que vous l’avez installée, enlevez (ou masquez) la ligne qui l’installe pour éviter des installations multiples chaque fois que vous exécutez le script. Autrement dit, vous devez installer l’extension une seule fois.↩︎
Notez la différence entre les lettres majuscules et minuscules. On utilise la fonction
str_to_lower()pour s’assurer que les caractères seront minuscules avant l’évaluation.↩︎
9.4 Comment évaluer les réponses?
Nos données représentent un questionnaire dont les questions ont des réponses correctes ou incorrectes. Cependant, le tableau ne nous donne pas la correction de chaque question. Naturellement, il faut avoir une clé de correction. Voici la clé :
Code
Maintenant, on colle les réponses dans notre tableau principal. Faites attention : on n’a que 10 réponses, mais notre tableau contient 180 lignes (nombre de participants = 18). Donc, il faut grouper les données avant d’ajouter la nouvelle colonne :
Code
Finalement, on peut corriger les réponses en utilisant la fonction
if_else().2Code
Le contenu du script
script_10_net.Rtermine ici. Le nettoyage des données n’est pas facile, mais c’est une partie essentielle dans notre analyse de données. On ne peut pas visualiser ni analyser les données si notre tableau est complètement chaotique. Les étapes de nettoyage suivies ci-dessus sont importantes n’importe quel le type de variable de réponse qu’on analyse. En plus, si jamais vous utilisez MS Forms pour créer un sondage, vous pouvez adapter le script utilisé en classe pour nettoyer vos propres données.Vu que nos données contiennent les dates de naissance des participants, on pourrait facilement calculer leurs âges. On utilise l’extension
lubridatepour analyser les dates (il s’agit d’une classe spéciale :date). Dans le code ci-dessus, la fonctionmdy()interprète les dates qui suivent le formatmois-jour-année. Ensuite, on calcule l’intervalle entre la date de naissance et aujourd’hui avec les fonctionsinterval()ettoday(), ce qui nous donnera le résultat en jours. Par conséquent, on divise le résultat par une année,years(1). Finalement, on arrondit le chiffre.Code