Retour à la leçon·Leçon 4 sur 8·Des données qui gardent leur sens
Les facteurs, et l'ordre qu'exige un rapport
Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.
Ce que couvre cette leçon
- Un facteur est un entier assorti d'une table de correspondance
- Le piège de
as.numeric() - Fixer l'ordre voulu
- Les facteurs ordonnés
- Les niveaux inutilisés, et les deux comportements qui divergent
- Réduire une longue traîne
- Facteurs et valeurs manquantes
- Là où les facteurs mordent dans une jointure
- Ce qui vient ensuite
Notes du présentateur
Ce qu'est réellement un facteur, le piège de as.numeric() qui renvoie silencieusement des positions de niveaux, et les verbes forcats qui mettent une échelle JMP dans l'ordre de l'échelle plutôt que dans celui de l'alphabet.Un facteur est un entier assorti d'une table de correspondance — En R
service <- factor(c("basic", "limited", "unimproved", "basic")) levels(service) #> [1] "basic" "limited" "unimproved" as.integer(service) #> [1] 1 2 3 1Notes du présentateur
En dessous, R stocke1 2 3 1et un vecteur de caractères contenant les niveaux. Tout ce qui suit — le problème d'ordre, le piège deas.numeric(), les niveaux inutilisés — découle de ce seul fait. Remarquez que les niveaux sont alphabétiques. Rien dansbasic,limited,unimprovedn'indique que ce soit l'ordre, et c'est exactement l'inverse pour une échelle de service du JMP, où non améliorée est le pire et où le service de base vaut mieux que le service limité. Laissé tel quel, chaque tableau et chaque graphique bâti sur cette colonne se lit dans un ordre qui ne signifie rien.Le piège de
as.numeric()— En Rage <- factor(c("10", "9", "8")) as.numeric(age) #> [1] 1 3 2Notes du présentateur
C'est l'erreur de facteur la plus coûteuse, et elle n'avertit pas.Le piège de
as.numeric()— En Ras.numeric(as.character(age)) #> [1] 10 9 8Notes du présentateur
Ce sont des positions de niveaux, non des valeurs. Les niveaux sont alphabétiques —"10","8","9"— donc"10"est en position 1 et"9"en position 3.as.character()d'abord, systématiquement. Le cas survient dès qu'une colonne numérique a été lue comme du texte — une colonne Excel avec un"n/a"égaré, un CSV lu encol_character()— puis convertie en facteur en chemin. Méfiez-vous d'une moyenne suspectement proche du nombre de catégories.Fixer l'ordre voulu — En R
library(forcats) ladder <- fct_relevel(service, "unimproved", "limited", "basic") levels(ladder) #> [1] "unimproved" "limited" "basic"Fixer l'ordre voulu — En R
fct_infreq(source) # le niveau le plus frequent en premier fct_reorder(name, value) # ordonner un facteur par une autre colonneNotes du présentateur
fct_relevel()nomme l'ordre explicitement. Déclarez-le une fois, près de l'endroit où la colonne est créée, et chaque tableau, graphique et modèle en aval en hérite. Deux verbes forcats gagnent immédiatement leur place :Fixer l'ordre voulu — En R
library(dplyr) by_commune |> mutate(commune = fct_reorder(commune, gam_rate)) |> ggplot2::ggplot(ggplot2::aes(gam_rate, commune)) + ggplot2::geom_col()Notes du présentateur
fct_reorder()est ce qui transforme un graphique en barres illisible en graphique lisible — les communes triées par leur taux de MAG plutôt que par l'alphabet — et il le fait sans unlevels =manuel à mettre à jour quand les données changent.Les facteurs ordonnés — En R
service[1] >= service[2] #> Warning: '>=' not meaningful for factors #> [1] NANotes du présentateur
fct_relevel()fixe l'ordre des niveaux. Il ne rend pas le facteur comparable :Les facteurs ordonnés — En R
ladder <- factor( c("basic", "limited"), levels = c("unimproved", "limited", "basic"), ordered = TRUE ) ladder[1] >= ladder[2] #> [1] TRUENotes du présentateur
Pour une échelle, où « au moins de base » est une vraie question, déclarez-la ordonnée :Les facteurs ordonnés
- Employez les facteurs ordonnés avec parcimonie — Ils changent la façon dont les modèles traitent la variable…
Notes du présentateur
>= "basic"calcule alors directement l'indicateur de couverture du JMP. Sansordered = TRUE, l'expression renvoieNAavec un avertissement — qui, s'il n'est pas lu, devient un chiffre de couverture àNAou, pire, un filtre qui ne sélectionne rien. Employez les facteurs ordonnés avec parcimonie. Ils changent la façon dont les modèles traitent la variable (contrastes polynomiaux plutôt qu'indicatrices), ce qui est rarement souhaité dans une régression. Pour une échelle de service, une bande de sévérité ou une phase IPC, l'ordre en vaut la peine. Pour une commune, non.Les niveaux inutilisés, et les deux comportements qui divergent — En R
d <- tibble::tibble(k = factor(c("a", "b", "a"), levels = c("a", "b", "c"))) nrow(dplyr::count(d, k)) #> [1] 2 length(table(d$k)) #> [1] 3Notes du présentateur
Un niveau sans ligne reste un niveau. Son apparition dans votre sortie dépend de la fonction interrogée, et R n'est pas cohérent avec lui-même sur ce point.Les niveaux inutilisés, et les deux comportements qui divergent — En R
dplyr::count(d, k, .drop = FALSE) # conserver le niveau vide droplevels(d$k) # retirer les niveaux sans ligne forcats::fct_drop(d$k) # la meme chose, en forcatsNotes du présentateur
count()écarte le niveau vide ;table()le conserve. Les deux sont justes pour des questions différentes, et la question est celle-là même que le cours Python pour les données de programme soulève à propos d'observed=: rapporter sur les formations ayant transmis des données veut le niveau vide en moins, et rapporter la couverture face à une liste de formations qui auraient dû transmettre le veut présent, car une formation à zéro ligne est justement le constat. Dites lequel vous voulez :Réduire une longue traîne — En R
source <- factor(wash$water_source) length(levels(source)) #> [1] 10 levels(fct_lump_n(source, 4)) #> [1] "borehole" "piped-into-dwelling" "piped-into-yard" "public-tap" "Other"Notes du présentateur
Dix sources d'eau, c'est trop de lignes pour un tableau de rapport et trop de couleurs pour un graphique.Réduire une longue traîne
- Ne repliez pas avant de calculer un indicateur —
Othermêle ici les sources protégées, qui sont améliorées, et l'eau…
Notes du présentateur
fct_lump_n()conserve les quatre plus fréquents et replie le reste dansOther. Ne repliez pas avant de calculer un indicateur.Othermêle ici les sources protégées, qui sont améliorées, et l'eau de surface, qui ne l'est pas : un taux de couverture calculé après repli est donc faux. Repliez pour la présentation, sur une copie, une fois les chiffres arrêtés.- Ne repliez pas avant de calculer un indicateur —
Réduire une longue traîne — En R
fct_recode(source, improved = "borehole", improved = "protected-well", unimproved = "surface-water" )Notes du présentateur
fct_recode()est l'alternative explicite et c'est ce qu'il faut pour une classification : elle nomme chaque correspondance, si bien qu'une source apparaissant au prochain export sans figurer dans la liste reste elle-même au lieu de rejoindre silencieusement un groupe.Facteurs et valeurs manquantes — En R
table(muac$outcome, useNA = "ifany")Notes du présentateur
NAn'est pas un niveau : il survit donc à tout réordonnancement et n'apparaît danstable()que si vous le demandez :Facteurs et valeurs manquantes — En R
muac <- muac |> mutate(outcome = fct_na_value_to_level(outcome, level = "non renseigne"))Notes du présentateur
Pour faire de l'absence une catégorie explicite — ce qui est souvent juste dans un rapport, où « non renseigné » est un constat et non un trou : Une fois devenue un niveau, elle sera comptée, tracée et sommée comme les autres. C'est le but, et c'est aussi le risque : un taux calculé sur un facteur incluant « non renseigné » n'a pas le même dénominateur qu'un taux qui l'exclut.Là où les facteurs mordent dans une jointure — En R
left_join(muac, sites, by = "commune")Notes du présentateur
Sicommuneest un facteur dans un tableau et du caractère dans l'autre, dplyr convertit et avertit. Si c'est un facteur dans les deux avec des niveaux différents, la jointure fonctionne quand même — dplyr compare les étiquettes, non les entiers — mais les niveaux du résultat sont l'union des deux, ce qui peut discrètement réintroduire des catégories vides. L'habitude la plus simple : joignez sur des colonnes de caractères, convertissez en facteur ensuite. Les facteurs sont un dispositif de présentation et de modélisation, non un type de clé.Ce qui vient ensuite
- Les colonnes portent désormais leur sens et leur ordre.
Notes du présentateur
Les colonnes portent désormais leur sens et leur ordre. L'unité suivante les travaille : les verbes dplyr, puis l'appel de regroupement où naissent la plupart des erreurs d'indicateurs.