如何用Tidyverse通过索引手动重排因子水平并排序数据框?
手动按索引调整因子水平并排序数据框的正确方法
你这里误用了fct_reorder()函数,它的作用是根据.x参数的数值大小重新排列因子水平,不是直接通过传入的索引来定义固定顺序,所以才会出现排序不符合预期的情况。
想要通过索引手动指定因子水平顺序,推荐用fct_relevel()或者直接修改因子的levels属性,以下是具体实现:
方法1:使用fct_relevel()(tidyverse推荐方式)
fct_relevel()可以直接传入原因子水平的索引,来定义新的顺序。你的原因子水平是:
levels(mydf$measure) # [1] "fast" "least strong" "less strong" "slow" # [5] "strong"
你想要的目标顺序是slow, least strong, less strong, strong, fast,对应原水平的索引分别是4,2,3,5,1,直接把这个索引向量传给fct_relevel()即可:
library(tidyverse) mydf <- data.frame(measure = c("strong", "less strong", "least strong", "fast", "slow"), cases = c(5,2,11,23,15), jan = c(2,1,3,4,1), feb = c(1,0,1,2,3)) mydf <- mydf %>% mutate(measure = factor(measure)) %>% # 按原水平索引指定新顺序 mutate(measure = fct_relevel(measure, c(4,2,3,5,1))) %>% arrange(measure) # 查看结果 print(mydf)
运行后得到的正确结果:
measure cases jan feb 1 slow 15 1 3 2 least strong 11 3 1 3 less strong 2 1 0 4 strong 5 2 1 5 fast 23 4 2
方法2:直接修改因子的levels属性
如果不想依赖forcats包,也可以直接提取原水平并按索引重排,再重新构造因子:
mydf <- mydf %>% mutate(measure = factor(measure)) %>% mutate(measure = { # 按索引提取原水平,生成新的水平顺序 new_levels <- levels(measure)[c(4,2,3,5,1)] factor(measure, levels = new_levels) }) %>% arrange(measure)
这个方法和fct_relevel()效果完全一致,适合习惯基础R操作的场景。
关键总结
fct_reorder():用于根据数值变量的大小动态排序因子水平,比如按某个数值列的均值排序因子,不是用来手动指定固定顺序的工具。fct_relevel()/直接修改levels:用于手动指定固定的因子水平顺序,支持通过原水平的索引操作,完美适配你因子标签过长的场景。
内容的提问来源于stack exchange,提问作者Amy M
相关产品推荐
相关产品推荐

