如何在ggplot2的百分比堆叠柱状图中按指定填充类别重排X轴
问题描述
我有如下数据集:
id=c(1,2,3,1,2,3,1,2,3) total_num=c(40,200,70,40,200,70,40,200,70) category=c(rep("level1",3),rep("level2",3),rep("level3",3)) value=c(30,160,50,6,30,15,4,10,5) df=data.frame(id,total_num,category,value) df$percent=round(df$value/df$total_num,3)
我生成了如下堆叠柱状图的代码:
mycolors<-c("#E78AC3","#E5C494","#66C2A5") library(forcats) df%>% ggplot(aes(x=reorder(id,-percent), y=percent, fill=factor(category,levels=c("level3","level2","level1"))))+ geom_bar(position="fill",stat="identity") + geom_text( data=df, aes(y=percent, label = ifelse(category == "level3", paste0(percent*100,"%"), "")), stat = "identity", position = position_stack(vjust = 0.5),size=2.5) + scale_fill_manual(values = mycolors, labels=c('Serious', 'Moderate','Normal')) + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1,size=10)) + labs(x="ID",y="",fill="Level") + scale_y_continuous(n.breaks=10,labels = scales::label_percent(accuracy = 1))
我希望按照category=="level3"(即图例中的"Serious")的百分比值对ID进行降序排列,理想顺序为1、3、2,请问如何修改上述代码?
解决方案
原代码中reorder(id,-percent)会默认用每个ID对应的所有percent均值排序,不符合需求。我们需要单独提取level3类别的百分比数据,以此为依据指定ID的排序顺序,具体修改如下:
mycolors<-c("#E78AC3","#E5C494","#66C2A5") library(forcats) library(dplyr) # 提取level3类别的百分比数据,用于排序 level3_percent <- df %>% filter(category == "level3") %>% select(id, percent) # 将ID转换为按level3百分比降序排列的因子 df$id <- factor(df$id, levels = level3_percent %>% arrange(desc(percent)) %>% pull(id)) # 绘制图表 df%>% ggplot(aes(x=id, y=percent, fill=factor(category,levels=c("level3","level2","level1"))))+ geom_bar(position="fill",stat="identity") + geom_text( data=df, aes(y=percent, label = ifelse(category == "level3", paste0(percent*100,"%"), "")), stat = "identity", position = position_stack(vjust = 0.5),size=2.5) + scale_fill_manual(values = mycolors, labels=c('Serious', 'Moderate','Normal')) + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1,size=10)) + labs(x="ID",y="",fill="Level") + scale_y_continuous(n.breaks=10,labels = scales::label_percent(accuracy = 1))
关键修改说明
- 先筛选出
category=="level3"的子集,获取每个ID对应的Serious类别百分比 - 将
df$id转换为因子类型,指定levels参数为按Serious百分比降序排列的ID序列 - 绘图时直接使用处理好的因子型
id,无需再调用reorder函数
修改后ID会按照Serious类别的百分比从高到低排列,得到你需要的1、3、2顺序。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

