You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ggplot分类变量手动排序失效,需保留顺序并显示样本量

解决ggplot添加样本量标签后分类顺序错乱的问题

问题背景

已通过fct_relevel手动指定bite_anatomy_other_variables数据框中species变量的排序顺序:

bite_anatomy_other_variables <- bite_anatomy_other_variables %>% 
   mutate(species = fct_relevel(species,
                                "Pet dog" , "Unowned dog" , "Dog (unknown status)",
                                "Pet cat" , "Unowned cat" , "Cat (unknown status)",
                                "Rat/rodent" , "Monkey" , "Livestock (cattle/goat/sheep/pig/horse)"))

但后续绘图时,使用paste0拼接物种名与样本量(格式为物种名\n(n = 数值))后,Y轴分类顺序变为非预期状态;未拼接标签时,手动排序的顺序可正常保留。需要实现显示带样本量的分类标签,同时保留手动设定的分类顺序。

问题原因

paste0会将因子类型的species转换为字符向量,字符向量的排序默认遵循字母顺序,导致之前用fct_relevel设定的因子顺序完全丢失。

解决方案

核心思路:在保留因子类型和原有水平顺序的前提下,修改因子的标签文本,而非将因子转换为字符。推荐使用forcats包的fct_relabel函数,它能直接对每个因子水平的标签进行修改,同时保留原顺序。

修正后的完整代码

bite_anatomy_other_variables %>%
  filter(!(species %in% c("Monkey", "Livestock (cattle/goat/sheep/pig/horse)"))) %>%
  add_count(species) %>%
  # 保留因子顺序,同时修改标签为带样本量的格式
  mutate(species = fct_relabel(species, function(x) {
    # 匹配每个物种对应的样本量n
    n_val <- n[match(x, species)]
    paste0(x, "\n(n = ", n_val, ")")
  })) %>%
  ggplot(mapping = aes(y = species, fill = body_part_collapsed)) +
  geom_bar(colour = "black", position = "fill") +
  scale_x_continuous(labels = c("0", "25%", "50%", "75%", "100%")) +
  labs(x = "Proportion of responses", y = "Animal species") +
  ggtitle("Body part exposed") 

另一种实现方式(手动映射标签)

如果需要更灵活的标签控制,可以先创建物种与带样本量标签的映射关系,再用fct_recode替换因子标签:

bite_anatomy_other_variables %>%
  filter(!(species %in% c("Monkey", "Livestock (cattle/goat/sheep/pig/horse)"))) %>%
  add_count(species) %>%
  # 创建物种到带样本量标签的映射
  group_by(species) %>%
  mutate(label = paste0(species, "\n(n = ", first(n), ")")) %>%
  ungroup() %>%
  # 保留原因子顺序,替换标签
  mutate(species = fct_recode(species, !!!setNames(unique(label), unique(species)))) %>%
  ggplot(mapping = aes(y = species, fill = body_part_collapsed)) +
  geom_bar(colour = "black", position = "fill") +
  scale_x_continuous(labels = c("0", "25%", "50%", "75%", "100%")) +
  labs(x = "Proportion of responses", y = "Animal species") +
  ggtitle("Body part exposed") 

内容的提问来源于stack exchange,提问作者Rakesh Chand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:05:02