ggplot2:按计数排序fill映射的堆叠条形图及多列扩展方法
问题描述
我希望使用数据框的单列绘制堆叠条形图,相关数据如下:
df Most_liked_Male 1 Mallika 207 2 Mallika 207 3 Mallika 207 4 Namaskar G 81 5 Mallika 207 6 Mallika 207 7 Mallika 207 8 Partech 28 9 Partech 29 10 Mallika 207 11 Mallika 12 Narasimha 13 Mallika 14 Mallika 15 Mallika 16 Mallika 17 Mallika 18 Mallika 19 Mallika 20 Mallika 21 Suraj-2 22 Mallika 23 Mallika-207 24 Mallika 25 Bhakti 26 Bhakti 27 Mallika 28 Bhakti 29 Bhakti 30 Mallika 31 Bhakti
我使用以下代码生成了堆叠条形图:
library(tidyverse) df$dummy <- c("dummy") ggplot(data = df, aes(x = dummy, fill = Most_liked_Male)) + geom_bar()
当前堆叠条形图的分段按字母顺序排列,我需要将其按计数排序。我找到的现有方案均要求将数据直接映射到x轴,但该方法不适用于我的数据。请问当数据通过fill参数引入时,如何按计数排序条形图的分段?
此外,我的数据中还有3列与示例列类似的列,若能将它们作为额外的堆叠条整合到同一张图中会很有帮助,当然也可以接受为每列单独生成图表。
解决方案
一、按计数排序堆叠分段
核心思路是将Most_liked_Male转换为按计数降序排列的因子,这样ggplot会按照因子水平的顺序渲染堆叠分段:
library(tidyverse) # 统计每个类别的出现次数并按降序排序 count_result <- df %>% count(Most_liked_Male, sort = TRUE) # 将原列转换为因子,水平顺序对应计数排序 df$Most_liked_Male <- factor(df$Most_liked_Male, levels = count_result$Most_liked_Male) # 重新绘制堆叠条形图 df$dummy <- "dummy" ggplot(data = df, aes(x = dummy, fill = Most_liked_Male)) + geom_bar()
二、处理多列数据的两种方案
方案1:整合为同一张图的多个堆叠条
先将宽格式数据转换为长格式,把列名作为x轴的分组维度,就能在同一张图里展示多列的堆叠条形:
# 假设你的目标列都是以"Most_liked_"开头,执行宽转长 long_df <- df %>% pivot_longer( cols = starts_with("Most_liked_"), names_to = "category", values_to = "name" ) %>% filter(!is.na(name)) # 过滤空值 # 为每个分类下的名称按计数排序因子水平 long_df <- long_df %>% group_by(category) %>% mutate(name = factor(name, levels = names(sort(table(name), decreasing = TRUE)))) # 绘制多堆叠条图表 ggplot(long_df, aes(x = category, fill = name)) + geom_bar() + labs(x = "类别", y = "计数", fill = "喜欢的对象")
方案2:为每列单独生成图表
用purrr工具批量处理,自动为每列生成独立的堆叠条形图:
# 提取所有目标列名称 target_cols <- df %>% select(starts_with("Most_liked_")) %>% colnames() # 批量生成图表 plots <- map(target_cols, function(col) { # 对当前列设置按计数排序的因子水平 temp_df <- df %>% mutate(!!col := factor(!!sym(col), levels = names(sort(table(!!sym(col)), decreasing = TRUE)))) # 绘制单列堆叠图 ggplot(temp_df, aes(x = "dummy", fill = !!sym(col))) + geom_bar() + labs(title = str_replace(col, "Most_liked_", "最喜欢的"), fill = "对象") }) # 查看单个图表,比如第一列的图 plots[[1]]
内容的提问来源于stack exchange,提问作者Ziggi
相关产品推荐
相关产品推荐

