ggplot2中多geom对应不同因子数据集时如何自定义X轴排序
多geom场景下按y值均值排序x轴的实现方案
核心逻辑:先基于所有用到的数据集全量计算x轴分类的排序规则,提前将x列转换为指定顺序的因子后再传入ggplot,避免单个geom的排序逻辑仅覆盖自身子集导致分类缺失。
基于现有复现代码(ach数据集)的操作
- 第一步:基于全量数据生成按pct均值降序排列的x轴分类序列
# 计算每个浏览器分类的平均pct,按均值从高到低排序 x_order <- ach[, .(mean_pct = mean(pct)), by = label][order(-mean_pct)]$label # 若需升序排列,改为 order(mean_pct) 即可 # 将label列转换为按上述顺序排列的因子,自动保留所有全量分类 ach[, label := factor(label, levels = x_order)]
- 第二步:直接运行原有ggplot代码即可,此时x轴已按pct均值排序,两个geom的所有分类都会正常显示。
针对初始拥有两个独立data.table(all_time、last_month)的优化方案
无需先rbind生成长表,直接全连接合并的效率更高:
- 第一步:全连接合并两个数据集,自动保留两个表中独有的分类
merged_dt <- merge(all_time, last_month, by = "label", all = TRUE, suffixes = c("_all", "_last"))
- 第二步:基于合并后的数据计算x轴排序规则
# 合并两个表的pct值计算均值,自动跳过空值 x_order <- merged_dt[, .(mean_pct = mean(c(pct_all, pct_last), na.rm = TRUE)), by = label][order(-mean_pct)]$label # 将两个原始数据集的label统一转换为指定顺序的因子 all_time[, label := factor(label, levels = x_order)] last_month[, label := factor(label, levels = x_order)]
- 第三步:运行原有绘图代码即可。
之前方案失效的核心原因:如果在单个geom的
aes()内部直接写reorder(label, pct, mean),排序规则仅基于该geom对应的子集数据,无法覆盖另一个geom独有的分类,最终会导致缺失geom的分类不在x轴显示范围内。
内容的提问来源于stack exchange,提问作者stilstuk
相关产品推荐
相关产品推荐

