使用列表合并因子级别

有时候需要将因子级别合并到更少的组中,这可能是因为其中一个类别中的数据稀疏。当你对类别名称进行不同的拼写或大小写时,也可能会发生这种情况。以这个因素为例

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

由于 R 区分大小写,因此该向量的频率表如下所示。

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

然而,该表并不代表数据的真实分布,并且类别可以有效地减少为三种类型:蓝色,绿色和红色。提供了三个例子。第一个说明了什么似乎是一个明显的解决方案,但实际上并没有提供解决方案。第二个提供了一个可行的解决方案,但是冗长且计算成本高。第三种不是一个明显的解决方案,但相对紧凑且计算效率高。

使用 factorfactor_approach)整合关卡

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

请注意,有重复的级别。我们仍然有三个类别为蓝色,它没有完成我们巩固水平的任务。此外,还有一个警告,即不推荐使用重复级别,这意味着此代码将来可能会生成错误。

使用 ifelseifelse_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

此代码生成所需的结果,但需要使用嵌套的 ifelse 语句。虽然这种方法没有任何问题,但管理嵌套的 ifelse 语句可能是一项繁琐的工作,必须小心谨慎。

使用列表整合因子级别(list_approach

合并级别的一种不太明显的方法是使用一个列表,其中每个元素的名称是所需的类别名称,元素是应该映射到所需类别的因子级别的字符向量。这具有直接处理因子的 levels 属性的附加优点,而无需分配新对象。

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

对每种方法进行基准测试

执行每种方法所需的时间总结如下。 (为了空间,未显示生成此摘要的代码)

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

列表方法的运行速度大约是 ifelse 方法的两倍。但是,除了非常非常大量的数据时,执行时间的差异很可能以微秒或毫秒来衡量。由于时间差异很小,效率无需指导决定使用哪种方法。相反,请使用熟悉且舒适的方法,以及你和你的协作者在将来的审核中将会理解的方法。