使用列表合并因子级别
有时候需要将因子级别合并到更少的组中,这可能是因为其中一个类别中的数据稀疏。当你对类别名称进行不同的拼写或大小写时,也可能会发生这种情况。以这个因素为例
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
然而,该表并不代表数据的真实分布,并且类别可以有效地减少为三种类型:蓝色,绿色和红色。提供了三个例子。第一个说明了什么似乎是一个明显的解决方案,但实际上并没有提供解决方案。第二个提供了一个可行的解决方案,但是冗长且计算成本高。第三种不是一个明显的解决方案,但相对紧凑且计算效率高。
使用 factor
(factor_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
请注意,有重复的级别。我们仍然有三个类别为蓝色,它没有完成我们巩固水平的任务。此外,还有一个警告,即不推荐使用重复级别,这意味着此代码将来可能会生成错误。
使用 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
此代码生成所需的结果,但需要使用嵌套的 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
方法的两倍。但是,除了非常非常大量的数据时,执行时间的差异很可能以微秒或毫秒来衡量。由于时间差异很小,效率无需指导决定使用哪种方法。相反,请使用熟悉且舒适的方法,以及你和你的协作者在将来的审核中将会理解的方法。