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
相关产品推荐
相关产品推荐

