Pour cette section, nous allons utiliser d’autres données d’exemple, également disponibles dans l’extension questionr
. Il s’agit d’un ensemble de trois tableaux de données (menages
, femmes
et enfants
) contenant les données d’une enquête de fécondité. Commençons par les charger en mémoire :
Les étiquettes de valeur
Les étiquettes de valeur consistent à attribuer une étiquette textuelle à certaines valeurs d’un vecteur. Elles ne peuvent s’appliquer qu’aux vecteurs numériques ou textuels.
Lorsqu’un vecteur possède des étiquettes de valeur, sa classe change et devient labelled
. Regardons déjà quelques exemples. Tout d’abord, jetons un apercu au contenu de l’objet femmes
grace à la fonction glimpse
de l’extension dplyr
.
Observations: 2,000
Variables: 17
$ id_femme <dbl> 391, 1643, 85, 881, 1981, 1072, 1978, 1607, 738, 165...
$ id_menage <dbl> 381, 1515, 85, 844, 1797, 1015, 1794, 1486, 711, 152...
$ poids <dbl> 1.803150, 1.803150, 1.803150, 1.803150, 1.803150, 0....
$ date_entretien <date> 2012-05-05, 2012-01-23, 2012-01-21, 2012-01-06, 201...
$ date_naissance <date> 1997-03-07, 1982-01-06, 1979-01-01, 1968-03-29, 198...
$ age <dbl> 15, 30, 33, 43, 25, 18, 45, 23, 49, 31, 26, 45, 25, ...
$ milieu <dbl+lbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...
$ region <dbl+lbl> 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, ...
$ educ <dbl+lbl> 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 0, ...
$ travail <dbl+lbl> 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ matri <dbl+lbl> 0, 2, 2, 2, 1, 0, 1, 1, 2, 5, 2, 3, 0, 2, 1, 2, ...
$ religion <dbl+lbl> 1, 3, 2, 3, 2, 2, 3, 1, 3, 3, 2, 3, 2, 2, 2, 2, ...
$ journal <dbl+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, ...
$ radio <dbl+lbl> 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, ...
$ tv <dbl+lbl> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, ...
$ nb_enf_ideal <dbl+lbl> 4, 4, 4, 4, 4, 5, 10, 5, 4, 5, 6, 10, 2, 6, 6, 6...
$ test <dbl+lbl> 0, 9, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, ...
Il apparaît que la variable region est de type haven_labelled
. On peut le confirmer avec class
.
[1] "labelled"
Regardons les premières valeurs prises par cette variable.
<Labelled double>
[1] 4 4 4 4 4 3
Labels:
value label
1 Nord
2 Est
3 Sud
4 Ouest
Nous voyons que quatre étiquettes de valeurs ont été associées à notre variable. Le code 1 correspond ainsi à la région Nord
, le code 2 à la région Est
, etc. Laissons de côté pour le moment la colonne is_na
que nous aborderons dans une prochaine section.
La liste des étiquettes est également renvoyée par la fonction describe
de questionr
.
[2000 obs.] Région de résidence
labelled double: 4 4 4 4 4 3 3 3 3 3 ...
min: 1 - max: 4 - NAs: 0 (0%) - 4 unique values
4 value labels: [1] Nord [2] Est [3] Sud [4] Ouest
n %
[1] Nord 707 35.4
[2] Est 324 16.2
[3] Sud 407 20.3
[4] Ouest 562 28.1
Total 2000 100.0
L’extension labelled
fournit la fonction val_labels
qui renvoie la liste des étiquettes de valeurs d’une variable sous la forme d’un vecteur nommé et la fonction val_label
(notez l’absence de ‘s’) qui renvoie l’étiquette associée à une valeur particulière. S’il n’y a pas d’étiquette de valeur, ces fonctions renvoient NULL
.
Nord Est Sud Ouest
1 2 3 4
[1] "Est"
NULL
NULL
Re-regardons d’un peu plus près les premières valeurs de notre variable region.
<Labelled double>
[1] 4 4 4 4 4 3
Labels:
value label
1 Nord
2 Est
3 Sud
4 Ouest
On s’aperçoit qu’il s’agit de valeurs numériques. Et l’affichage indique que notre variable est plus précisément du type haven_labelled double
. Pour rappel, double
est synonyme de numeric
. Autrement dit, la classe haven_labelled
ne modifie pas le type sous-jacent d’un vecteur, que l’on peut toujours obtenir avec la fonction typeof
. Nous pouvons également tester si notre variable est numérique avec la fonction is.numeric
.
[1] "double"
[1] TRUE
À la différence des facteurs, le type original d’une variable labellisée n’est pas modifié par la présence d’étiquettes de valeur. Ainsi, il reste possible de calculer une moyenne à partir de notre variable region (même si cela n’est pas pertinent ici d’un point de vue sémantique).
[1] 2.412
Avec un facteur, nous aurions eu un bon message d’erreur.
Warning in mean.default(d$nivetud): argument is not numeric or logical:
returning NA
[1] NA
Nous allons voir qu’il est aussi possible d’associer des étiquettes de valeurs à des vecteurs textuels. Créons tout d’abord un vecteur textuel qui nous servira d’exemple.
[1] "f" "f" "h" "f" "h"
Le plus facile pour lui associer des étiquettes de valeur est d’utiliser val_label
.
<Labelled character>
[1] f f h f h
Labels:
value label
f femmes
h hommes
[1] "character"
Notre vecteur v
a automatiquement été transformé en un vecteur de la classe labelled
. Mais son type sous-jacent est resté "character"
. Par ailleurs, les données elle-même n’ont pas été modifiées et ont conservé leurs valeurs originales.
Il est également possible de définir/modifier/supprimer l’ensemble des étiquettes de valeur d’une variable avec val_labels
en lui assignant un vecteur nommé.
<Labelled character>
[1] f f h f h
Labels:
value label
h Homme
f Femme
i Valeur indéterminée
Comme précédemment, on utilisera NULL
pour supprimer une ou toutes les étiquettes.
<Labelled character>
[1] f f h f h
Labels:
value label
h Homme
f Femme
[1] "f" "f" "h" "f" "h"
[1] "character"
Si l’on supprime toutes les étiquettes de valeur, alors notre vecteur retrouve sa classe initiale.
Assignation et condition
Les étiquettes de valeur sont plus souples que les facteurs, en ce sens qu’il n’est pas obligatoire d’indiquer une étiquette pour chaque valeur prise par une variable. Alors qu’il n’est pas possible avec un facteur d’assigner une valeur qui n’a pas été préalablement définie comme une des modalités possibles du facteur, nous n’avons pas cette limite avec les vecteurs labellisés.
Important : quand on assigne une valeur à un facteur, on doit transmettre le texte correspondant à la modalité, alors que pour un vecteur labellisé on transmettra le code sous-jacent (pour rappel, les étiquettes de valeur ne sont qu’une information additionnelle).
De plus, nous avons vu que les données initiales n’étaient pas modifiées par l’ajout ou la suppression d’étiquettes de valeur, alors que pour les facteurs ce n’est pas vrai. Pour mieux comprendre, essayons la commande suivante :
[1] 1 1 2 1 2
attr(,"levels")
[1] "f" "h"
Un facteur stocke de manière interne les valeurs sous la forme d’une suite d’entiers, démarrant toujours par 1, forcément consécutifs, et dont les valeurs dépendent de l’ordre des facteurs. Pour s’en rendre compte :
[1] 2 2 1 2 1
attr(,"levels")
[1] "h" "f"
[1] 1 1 2 1 2
attr(,"levels")
[1] "f" "h"
Ce qui importe pour un facteur ce sont les modalités de ce dernier tandis que pour un vecteur labellisé ce sont les valeurs du vecteur elles-mêmes. Cela reste vrai pour l’écriture de conditions.
Prenons un premier exemple avec un facteur :
[2000 obs.]
nominal factor: "Homme" "Femme" "Homme" "Homme" "Femme" "Femme" "Femme" "Homme" "Femme" "Homme" ...
2 levels: Homme | Femme
NAs: 0 (0%)
n %
Homme 900 45
Femme 1100 55
Total 2000 100
FALSE TRUE
1100 900
FALSE
2000
La condition valide est celle utilisant "Homme"
qui est la valeur de la modalité du facteur.
Et avec un vecteur labellisé ?
[2000 obs.] Milieu de résidence
labelled double: 2 2 2 2 2 2 2 2 2 2 ...
min: 1 - max: 2 - NAs: 0 (0%) - 2 unique values
2 value labels: [1] urbain [2] rural
n %
[1] urbain 912 45.6
[2] rural 1088 54.4
Total 2000 100.0
FALSE
2000
FALSE TRUE
1088 912
Ici, pour être valide, la condition doit porter sur les valeurs de la variable elle-même et non sur les étiquette.