如何在ggplot2中对分组条形图的条形按频率从小到大排序?
解决分组条形图按频率排序的问题
要实现每个trans类别下的class条形按对应组合的频数从小到大排列,你之前用forcats::fct_infreq(class)无效的原因是:这个函数是按class在整个数据集的总频数排序,而非每个trans分组内的频数排序。
你可以先统计出每个trans-class组合的频数,再对每个trans内的class按频数排序后绘图,具体步骤如下:
步骤1:预处理数据,计算频数并排序
library(ggplot2) library(dplyr) # 统计每个trans和class的组合频数,并在每个trans内按频数从小到大排序 mpg_sorted <- mpg %>% count(trans, class, name = "freq") %>% group_by(trans) %>% arrange(freq) %>% # 为每个trans内的class设置排序后的因子水平 mutate(class_sorted = factor(class, levels = class)) %>% ungroup()
步骤2:绘制排序后的分组条形图
ggplot(mpg_sorted, aes(x = freq, y = trans, fill = class_sorted, group = class_sorted)) + geom_col(position = position_dodge2(preserve = "single")) + labs(fill = "class") # 保持图例名称不变
关键说明:
- 用
count()统计组合频数,避免geom_bar自动统计时无法直接利用频数排序 group_by(trans) %>% arrange(freq)确保每个trans内的class按频数从小到大排列factor(class, levels = class)把排序后的class顺序转为因子水平,ggplot会按这个顺序绘制条形position_dodge2(preserve = "single")确保每个trans下的条形间距一致,避免因类别数量不同导致的错位
如果希望按class的全局总频数排序(而非分组内频数),可以修改预处理步骤,用全局频数排序class:
mpg_global_sorted <- mpg %>% count(class, name = "total_freq") %>% arrange(total_freq) %>% mutate(class_sorted = factor(class, levels = class)) %>% right_join(mpg, by = "class") %>% count(trans, class_sorted, name = "freq") ggplot(mpg_global_sorted, aes(x = freq, y = trans, fill = class_sorted, group = class_sorted)) + geom_col(position = position_dodge2(preserve = "single")) + labs(fill = "class")
内容的提问来源于stack exchange,提问作者shani
相关产品推荐
相关产品推荐

