数据分析中如何用case_when转因子并保持顺序,无需重复指定levels?
解决case_when生成因子时自动匹配判断顺序的问题
嗨,这个需求我太懂了——每次手动重复写levels真的很繁琐,其实用forcats包的fct_inorder()函数就能完美解决,完全不用重复指定等级顺序!我给你演示具体用法:
首先补全你的示例代码,然后用两种方式实现,重点推荐第一种:
方法1:用fct_inorder()自动继承case_when的判断顺序
library(dplyr, warn.conflicts = FALSE) library(forcats) # 它是tidyverse的一部分,加载起来很方便 set.seed(1234) score <- runif(100, min = 0, max = 100) # 生成数据框并编码等级 df <- tibble(score) %>% mutate( # 先按case_when的逻辑生成字符型等级 grade = case_when( score >= 90 ~ "Excellent", score >= 70 ~ "Good", TRUE ~ "Fail" ), # 用fct_inorder转成因子,自动按首次出现的顺序设为水平 grade = fct_inorder(grade) ) # 验证因子水平是否符合预期 levels(df$grade) #> [1] "Excellent" "Good" "Fail"
为什么这个方法有效?
case_when是从上到下依次判断的,所以"Excellent"会比"Good"先出现在grade向量里,"Good"又比"Fail"早出现。而fct_inorder()的作用就是按照向量中元素首次出现的顺序来设置因子水平,刚好和你想要的等级顺序完全匹配,全程不用手动写levels参数!
方法2:不加载forcats的base R替代方案
如果你不想额外加载包,也可以用base R的factor()结合unique(),不过要确保数据中每个等级至少出现一次(否则unique()会漏掉未出现的等级):
df <- tibble(score) %>% mutate( grade = case_when( score >= 90 ~ "Excellent", score >= 70 ~ "Good", TRUE ~ "Fail" ), grade = factor(grade, levels = unique(grade)) )
总结下来,fct_inorder()是最简洁且可靠的方案,完全省去重复写levels的麻烦!
内容的提问来源于stack exchange,提问作者user5068121
相关产品推荐
相关产品推荐

