R Language Consolidation des niveaux de facteurs avec une liste


Exemple

Il y a des moments où il est souhaitable de consolider les niveaux de facteurs en moins de groupes, peut-être en raison de la rareté des données dans l'une des catégories. Cela peut également se produire lorsque vous avez des orthographes ou des majuscules variables pour les noms de catégories. Prenons comme exemple le facteur

set.seed(1)
colorful <- sample(c("red", "Red", "RED", "blue", "Blue", "BLUE", "green", "gren"),
                   size = 20,
                   replace = TRUE)
colorful <- factor(colorful)

Puisque R est sensible à la casse, une table de fréquence de ce vecteur apparaîtra comme ci-dessous.

table(colorful)
colorful  
blue  Blue  BLUE green  gren   red   Red   RED  
   3     1     4     2     4     1     3     2

Ce tableau, cependant, ne représente pas la distribution réelle des données et les catégories peuvent être réduites à trois types: bleu, vert et rouge. Trois exemples sont fournis. La première illustre ce qui semble être une solution évidente, mais ne fournira pas de solution. La seconde donne une solution de travail, mais est coûteuse et verbeuse. La troisième n'est pas une solution évidente, mais elle est relativement compacte et efficace en termes de calcul.

Consolidation des niveaux à l'aide du factor ( factor_approach factor )

factor(as.character(colorful),
       levels = c("blue", "Blue", "BLUE", "green", "gren", "red", "Red", "RED"),
       labels = c("Blue", "Blue", "Blue", "Green", "Green", "Red", "Red", "Red"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Blue Blue Green Green Red Red Red
Warning message:
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated

Notez qu'il existe des niveaux dupliqués. Nous avons toujours trois catégories pour "Blue", ce qui ne complète pas notre tâche de consolidation des niveaux. En outre, il existe un avertissement indiquant que les niveaux dupliqués sont obsolètes, ce qui signifie que ce code peut générer une erreur à l'avenir.

Consolidation des niveaux à l'aide de ifelse ( ifelse_approach )

factor(ifelse(colorful %in% c("blue", "Blue", "BLUE"),
       "Blue",
       ifelse(colorful %in% c("green", "gren"),
              "Green",
              "Red")))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

Ce code génère le résultat souhaité, mais nécessite l'utilisation d'instructions ifelse imbriquées. Bien qu'il n'y ait rien de mal à cette approche, la gestion des instructions ifelse imbriquées peut être une tâche fastidieuse et doit être effectuée avec soin.

Consolidation des niveaux de facteurs avec une liste ( list_approach )

Une manière moins évidente de consolider les niveaux consiste à utiliser une liste où le nom de chaque élément correspond au nom de la catégorie souhaitée et où l’élément est un vecteur de caractère des niveaux du facteur qui doivent correspondre à la catégorie souhaitée. Cela présente l'avantage supplémentaire de travailler directement sur l'attribut levels du facteur, sans devoir affecter de nouveaux objets.

levels(colorful) <- 
     list("Blue" = c("blue", "Blue", "BLUE"),
          "Green" = c("green", "gren"),
          "Red" = c("red", "Red", "RED"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

Benchmarking chaque approche

Le temps requis pour exécuter chacune de ces approches est résumé ci-dessous. (Par souci d’espace, le code pour générer ce résumé n’est pas affiché)

Unit: microseconds
          expr     min      lq      mean   median      uq     max neval cld
        factor  78.725  83.256  93.26023  87.5030  97.131 218.899   100  b 
        ifelse 104.494 107.609 123.53793 113.4145 128.281 254.580   100   c
 list_approach  49.557  52.955  60.50756  54.9370  65.132 138.193   100 a

L'approche de la liste est environ deux fois plus rapide que celle de l'approche ifelse . Cependant, sauf en cas de très, très grande quantité de données, les différences de temps d'exécution seront probablement mesurées en microsecondes ou en millisecondes. Avec de si petites différences de temps, l'efficacité ne doit pas guider la décision de l'approche à utiliser. Au lieu de cela, utilisez une approche familière et confortable que vous et vos collaborateurs comprendrez lors de futures révisions.