DU Bii - module 3: R and stats


Session 2: R base

Tutorial on factors - Claire Vandiedonck

1. Qu’est-ce qu’un facteur?

Les variables catégoriques peuvent prendre des valeurs numériques ou être des chaines de caractères. Pour les utiliser de manière correcte en modélisation statistique et tester leur impact sur d’autres variables, il est nécessaire de les transformer en facteurs qui doivent être des entiers, ce qui peut nécessiter une conversion. Certaines fonctions sous R le font de manière cachée : c’est le cas de boxplot!

Exemple: Ci-dessous, on affiche la distribution de la consommation en carburant (variable mpg = miles per gallon) en fonction du nombre de cylindres (variable cyl). En statistiques, le nombre de cylindres est un facteur avec 3 niveaux 4,6 et 8). Mais quand on regarde la structure du dataframe mtcasr le type est numérique et non un facteur.

str(mtcars) boxplot(data=mtcars, mpg~cyl)

Si transformez la variable "cyl" en variable avec une chaîne de caractères en ajoutant par exemple "cyl_" devant la valeur numérique, la fonction boxplot sera toujours capable de traiter cette variable comme un facteur.

2. Conversion en facteur avec la fonction factor():

La fonction factor() permet de convertir vous-même un vecteur (une variable) en un facteur qui encode les différentes valeurs possibles de la variable.

Sous R, les valeurs entières de 1 à n correspondront aux index du facteur. Ces valeurs d’index ou « codes » sont attribuées par défaut selon l’ordre alphabétique ou numérique (cf. help(factor)) des différentes valeurs possibles, appelés niveaux ou levels de la variable.

Elles sont elles-mêmes renumérotées ou ré-indexées de 1 à n ! Par exemple, si vous avez les entiers de 4 à 10 dans un vecteur v1 :

La factorisation de v1 a donc créé un 1 facteur à 7 niveaux correspondant aux valeurs catégoriques “4” à “10” mais indexées 1 à 7 !

Elles sont indexées de 1 à n : Par exemple, si je factorise le vecteur suivant contenant 4 valeurs :

Les valeurs “Homme” et “Femme” auront respectivement comme index les valeurs 2 et 1 car “Femme” sort avant “Homme” selon l’ordre alphabétique. Les valeurs 1, 3 et 4 du vecteur v2 seront donc codées 2, tandis que la 2ème sera codée 1, ce que vous voyez en regardant la structure du facteur créé :

Mais ce n’est cependant pas nécessairement le code que vous voulez garder : souvent on met « 2 » pour les femmes et « 1 » pour les « hommes ». De même, “cas” et “controles” seront convertis en 1 et 2. Or il est souvent préférable de donner la valeur 1 à la référence à laquelle on compare et donc on peut souhaiter imposer que 1 corresponde aux “controles” et 2 aux “cas”

3. Choisir les niveaux d'un facteur

Il peut donc être nécessaire d’imposer par vous-mêmes l’ordre de votre choix qui ne serait pas alphabétique ou numérique. L’argument levels permet d’imposer cet ordre.

En utilisant la fonction factor(), vous pouvez utiliser en particulier deux arguments pour choisir vous- même l’ordre des niveaux d’une part et leurs noms d’autre part:

1. L’argument levels permet de préciser l’ordre de vos niveaux dans un ordre qui pourrait être différent de l’ordre alphabétique ou numérique.

2. L’argument labels permet de renommer chaque niveau du facteur, sans modifier l’ordre par défaut ou spécifié par levels. Par exemple, vous voulez renommer “Homme” par “Man” et “Femme” par “Woman”.

Pour ces deux arguments, vous donnez un vecteur avec les noms des niveaux.

4. Exemple pas à pas illustrant l’usage de factor() avec les arguments levels et labels

Prenez par exemple le vecteur d’un score de satisfaction à une enquête:

a- conversion en facteur

Vous pouvez le convertir en un facteur avec la fonction factor()

L’objet obtenu est un facteur à 3 niveaux recodés par les index 1, 2 et 3.

Vous ne voyez pas les index directement, mais ils sont visibles si vous utiliser la fonction str(). Voir un peu plus bas.

Par défaut, les codes/index 1 à n sont donnés aux niveaux selon l’ordre alphabétique des valeurs uniques. Dans l’exemple, “acceptable” est donc recodé 1, “bon” 2 et “mauvais” 3. Avant de factoriser, vous pouvez identifier l’ordre avec sort() appliqué aux valeurs uniques de votre vecteur de départ.

Vous retrouvez cet ordre avec la fonction levels()appliquée à votre facteur.

Ainsi, “acceptable” a l’index 1, “bon” l’index 2 et “mauvais” l’index 3 du vecteur levels Si vous regardez la structure de votre facteur avec la fonction str(), vous obtenez bien un facteur à 3 niveaux, dont le nom trié alpha-numériquement correspondant au résultats de levels() est donné, suivi de l’affichage des premières valeurs codées. Ici, vous obtenez 3 puis 2 puis 1 puis 2 puis 2 puis 3, correspondant aux index/codes des niveaux

b -recodage des niveaux du facteurs

Si vous voulez imposer que “mauvais” soit codé par 1, “acceptable” par 2 et “bon” par 3, vous ajoutez ces 3 niveaux dans cet ordre au moment de créer votre facteur avec l’argument level auquel vous donnez le vecteur_des_niveaux_du_facteur_dans_ordre_souhaité, par exemple de 1 à 3 du moins bon au meilleur. Dans l’exemple, j’ajoute “2” au nom de ce nouvel objet R:

Vous constatez alors avec la fonction str() que les données sont désormais 1, puis 3, puis 2, puis 3 etc…selon les niveaux choisis :

c - renommage des niveaux du facteur

Si maintenant vous souhaitez en plus renommer les niveaux par “bad”, “satisfactory”, “good”, vous ajoutez l’argument “labels” dans une version 3:

Si vous regardez la structure et à quels index correspondent les données, c’est dans l’ordre souhaité comme dans le facteur version 2.

Et vous pouvez voir la reconversion des noms des niveaux:

Attention toutefois lorsque vous utilisez l’argument “labels” dans l’ordre souhaité en oubliant d’utiliser l’argument “levels”
car vous aboutissez à remplacer les valeurs de façon incorrecte. La version 4 ci-dessous n’est pas du tout celle souhaitée et a remplacé les données !

- les facteurs en R sont utilisés pour les statistiques et les figures - il est préférable de contrôler soi-même les niveaux afin de mettre la valeur "1" à la référence - l'argument stringsAsFactors=TRUE est dangereux car il peut conduire à des conversions incontrôlées. Ce paramètre par défaut a heuresement était modifié en `FALSE` à partir de la version 4 de R. C'est également le cas pour Tydiverse avec les tibbles.