如何在ggplot中按fill变量将对应条形分组排列?
解决方案
要实现按circumstances_bite_broad分组(同颜色条形聚集),同时保持组内按circumstances_bite的频率排序,核心是重新调整circumstances_bite的因子水平顺序——先按分组变量归类,再在组内按频率排序。
方法一:先统计排序再设置因子水平
这种方法逻辑清晰,便于调整细节:
- 先统计每个细分场景(
circumstances_bite)的频数,同时关联其所属的大类(circumstances_bite_broad) - 按大类和频数降序排序,用这个排序结果重新定义
circumstances_bite的因子水平 - 基于调整后的数据集绘图
# 1. 统计并排序各场景的频数与所属大类 count_data <- sur %>% select(circumstances_bite, circumstances_bite_broad) %>% drop_na() %>% count(circumstances_bite, circumstances_bite_broad, name = "freq") %>% arrange(circumstances_bite_broad, desc(freq)) # 先按大类分组,组内按频数降序 # 2. 调整因子水平,让ggplot按指定顺序排列 sur_clean <- sur %>% select(circumstances_bite, circumstances_bite_broad) %>% drop_na() %>% mutate(circumstances_bite = factor(circumstances_bite, levels = count_data$circumstances_bite)) # 3. 绘制条形图 ggplot(sur_clean, aes(y = circumstances_bite, fill = circumstances_bite_broad)) + geom_bar() + xlab("No of people") + ylab("circumstance of bite") + ggtitle("circumstance of bite by a pet dog")
方法二:直接在ggplot中调整因子顺序
如果不想额外处理数据集,可以用forcats包的fct_reorder函数,在aes中直接指定排序规则:
library(forcats) sur %>% select(circumstances_bite, circumstances_bite_broad) %>% drop_na() %>% ggplot(aes( y = fct_reorder( circumstances_bite, .by = circumstances_bite_broad, # 先按大类分组 .fun = function(x) length(x) # 组内按细分场景的频数排序 ), fill = circumstances_bite_broad )) + geom_bar() + xlab("No of people") + ylab("circumstance of bite") + ggtitle("circumstance of bite by a pet dog")
原理说明
ggplot中离散变量的排列顺序由因子的水平顺序决定。你原来的代码用fct_infreq只按单个变量的频率排序,忽略了分组变量;现在通过先按circumstances_bite_broad分组,再在组内按频率排序重新定义因子水平,就能实现同颜色条形聚集的效果。
内容的提问来源于stack exchange,提问作者Rakesh Chand
相关产品推荐
相关产品推荐

