You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言50项调研排名数据ggplot2可视化优化咨询

排名数据可视化优化方案

原始问题背景

有一份调研排名数据,要求受访者对50个条目按1-5级优先级排序,原始数据示例:

Rank1 <- c("Item 1", "Item 3", "Item 6")
Rank2 <- c("Item 6", "Item 9", "Item 10")
Rank3 <- c("Item 45", "Item 6", "Item 10")
Rank4 <- c("Item 12", "Item 32", "Item 34")
Rank5 <- c("Item 22", "Item 5", "Item 21")

df <- data.frame(Rank1, Rank2, Rank3, Rank4, Rank5)

数据转置后将条目映射为数值编码,结构如下(P1-P5为受访者):

P1 <- c(1, 3, 6, 3, 40)
P2 <- c(6, 9, 10, 11, 30)
P3 <- c(1, 3, 10, 11, 30)
P4 <- c(1, 3, 10, 2, 5)
P5 <- c(22, 5, 21, 11, 30)

df <- data.frame(P1, P2, P3, P4, P5)

当前通过手动统计每行条目出现次数、计算占比后用ggplot2绘制堆叠柱形图,展示每个条目在1-5级排名中的相对占比,代码如下:

# 手动统计条目出现次数
df$item_1 <- rowSums(df == 1)
df$item_2 <- rowSums(df == 2)
df$item_3 <- rowSums(df == 3)
df$item_4 <- rowSums(df == 5)
df$item_5 <- rowSums(df == 6)
df$item_6 <- rowSums(df == 9)
df$item_7 <- rowSums(df == 10)
df$item_8 <- rowSums(df == 40)
df$item_9 <- rowSums(df == 11)
df$item_10 <- rowSums(df == 30)
df$item_11 <- rowSums(df == 22)
df$item_12 <- rowSums(df == 21)

# 生成计数子表
df_counts <- subset(df, select = 6:17)
df_counts$counts <- Reduce(`+`, lapply(df_counts, `>`, 0))

# 计算相对占比
library(data.table)
df_counts<-setDT(df_counts)[,.SD/counts]

# 绘图
df_final_1<-reshape2::melt(df_counts)
df_final_1$rowid<-1:5

library(ggplot2)
ggplot(df_final_1, aes(x=variable, y=value)) + 
  geom_bar(aes(y = value,
               x= rowid,
               fill=factor(variable)),
           data=df_final_1,
           stat="identity",
           width = 0.8) +
  labs(x="Ranking", y="Share")

当前遇到的问题:

  • 50个条目绘制的堆叠柱形图非常杂乱,占比较小的条目几乎不可见,1级排名占比最高,2-4级的条目分布无法清晰展示,效果如下图:
    50个排名条目占比效果图

优化建议

一、数据处理流程优化

首先替换手动统计条目的代码,用长表转换自动完成计数,适配任意数量的条目,避免手动编码出错:

library(tidyverse)
# 直接将原始编码后的宽表转为长表,一步统计各排名下的条目占比
df_long <- df %>% 
  mutate(rank = 1:nrow(.)) %>% 
  pivot_longer(cols = -rank, names_to = "respondent", values_to = "item") %>% 
  group_by(rank, item) %>% 
  summarise(count = n(), .groups = "drop") %>% 
  group_by(rank) %>% 
  mutate(share = count/sum(count))

以上代码无需针对50个条目做任何修改,自动完成所有统计计算。

二、可视化优化

1. 精简分类减少干扰

先统计每个条目的总占比,将总占比低于2%(可根据实际情况调整阈值)的条目统一合并为「其他」类别,大幅减少图例数量,核心条目辨识度直接提升。

# 示例合并低占比条目
item_total <- df_long %>% 
  group_by(item) %>% 
  summarise(total_share = sum(share), .groups = "drop") %>% 
  mutate(item_new = ifelse(total_share < 0.02, "其他", as.character(item)))

df_long <- df_long %>% left_join(item_total, by = "item")

2. 更换更适配的图表类型

堆叠柱形图本身不适合展示超过10个分类的占比,推荐替换为以下类型:

  • 热力图:X轴设为1-5级排名,Y轴设为条目,按条目总优先级得分排序Y轴,颜色深浅代表占比高低。不需要额外图例也能快速看出高优先级条目集中在哪个排名段,低优先级条目的分布也一目了然。
  • 分面分组图:把50个条目按总占比分为高/中/低关注度3组,每组单独绘制小的堆叠柱形图,同组内条目数量少,不会出现堆叠过密的问题。
  • 斜率图:如果重点关注不同排名层级的条目变化,用斜率图连接同一条目在不同排名的占比点,清晰展示变化趋势。

3. 解决低占比条目看不见的问题

如果需要保留所有条目且用静态堆叠柱形图,可做以下调整:

  • 调整Y轴展示逻辑:1级排名单独做一个子图,Y轴范围0-1;2-5级排名做另一个子图,Y轴范围设为0到这几个等级的最大占比,不用强行和1级对齐,低占比的部分会自然放大。
  • 仅为占比高于3%的部分添加数值标签,低占比部分不显示文字避免拥挤。
  • 图例按条目总占比从高到低排序,和堆叠顺序保持一致,方便对应查找。

4. 改用交互图

如果是在线展示场景,直接用plotly包将静态图转为交互图,鼠标悬停就能看到对应块的条目名称、占比数值,不需要挤在静态图里放全部图例。


内容的提问来源于stack exchange,提问作者zepmaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 01:36:03