在2×2分面窗口中计算物种贡献占比并降序排序ggplot条形图
问题描述
我是R语言新手,首次提问,若有信息遗漏敬请谅解。我需要绘制两个村庄、两个时间段内物种的贡献占比图:按time_period和Village分组,计算每个物种的Percent(公式为100*TL_abundance/sum(TL_abundance)),在2×2分面中展示,且每个分面仅显示前15个物种,并按Percent降序排列。但尝试fct_reorder和reorder_within后,物种排序错误,还出现X轴对齐问题。
以下是我尝试的代码:
# 代码1 SpeciesI %>% group_by(time_period,Village) %>% mutate(Percent=100*TL_abundance/sum(TL_abundance)) %>% ggplot(aes(x=FinalSpecies, y=Percent))+ geom_bar(stat="identity")+ facet_wrap(time_period~Village, scales="free_x")+ coord_cartesian(xlim =c(1, 15))+ labs(x="Species", y="Percentage")+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) # 代码2 SpeciesI %>% group_by(time_period,Village) %>% mutate(Percent=100*TL_abundance/sum(TL_abundance)) %>% ggplot(aes(x=reorder_within(FinalSpecies,-Percent,time_period), y=Percent))+ geom_bar(stat="identity")+ facet_wrap(time_period~Village, scales="free_x")+ coord_cartesian(xlim =c(1, 15))+ scale_x_reordered() + labs(x="Species", y="Percentage")+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
解决方案
你的问题核心是没有先筛选出每个分组内的前15个物种,仅用coord_cartesian(xlim=c(1,15))截断显示会导致排序逻辑混乱;另外reorder_within的分组维度没包含Village,排序只按时间周期,没考虑村庄分组。
按以下步骤修改:
- 分组计算百分比后,直接筛选每个
time_period+Village组内Percent前15的物种 - 在每个组合分组内对物种按
Percent降序排序,reorder_within需同时绑定两个分组变量 - 用
scale_x_reordered()修正X轴标签显示
修改后的代码:
library(tidyverse) library(tidytext) # 提供reorder_within和scale_x_reordered函数 SpeciesI %>% # 分组计算物种占比 group_by(time_period, Village) %>% mutate(Percent = 100 * TL_abundance / sum(TL_abundance)) %>% # 筛选每个组内前15个高占比物种 slice_max(Percent, n = 15) %>% ungroup() %>% ggplot(aes(x = reorder_within(FinalSpecies, -Percent, .group = interaction(time_period, Village)), y = Percent)) + geom_bar(stat = "identity") + # 分面保留独立X轴 facet_wrap(time_period ~ Village, scales = "free_x") + scale_x_reordered() + # 移除X轴标签的分组后缀 labs(x = "物种", y = "占比(%)") + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
关键说明:
slice_max(Percent, n=15)直接过滤每个分组的目标物种,避免数据残留导致的排序错误interaction(time_period, Village)确保排序是在村庄+时间段的组合分组内进行,而非仅按时间周期- 若未安装
tidytext包,先运行install.packages("tidytext")完成安装
内容的提问来源于stack exchange,提问作者Fishydata
相关产品推荐
相关产品推荐

