如何使用ggplot与tidyverse将同主题受访者的回答柱状图紧邻展示
解决同主题亲子回答柱状图紧邻排列的问题
问题核心
你的数据集将儿童和父母的问题分开存储(如"I like birds"对应儿童、"My baby likes birds"对应父母),导致ggplot将每个问题视为独立类别,无法实现同主题下两类受访者的柱子并排对比。针对40+问题的场景,无需手动调整,可通过数据清洗提取统一主题来解决。
步骤1:修正并清洗数据集
首先修正原数据集的行数不匹配问题,再通过字符串处理自动提取核心主题:
library(tidyverse) # 修正后的示例数据集(每个问题对应多份观测值) ds = data.frame( question = rep(c("I like birds", "My baby likes birds", "I like dogs", "My baby likes dogs"), each = 3), resp = rep(c("child", "parent", "child", "parent"), each = 3), value = c(1,2,3,4,5,6,3,2,1,1,2,3) ) # 自动提取核心主题(适配"I like X"和"My baby likes X"的模式) ds_cleaned <- ds %>% mutate( topic = str_extract(question, "(?<=likes )\\w+") )
如果你的问题表述有其他模式,可调整正则表达式:比如问题含"enjoy"时,可改为"(?<=likes|enjoy )\\w+";若主题是短语,可调整匹配规则。
步骤2:绘制目标图表
以提取的topic作为x轴,resp作为填充分组,使用position_dodge实现柱子并排:
ggplot(ds_cleaned, aes(x = topic, y = value, fill = resp)) + # 绘制均值柱状图,设置 dodge 宽度 geom_bar(stat = "summary", fun = "mean", position = position_dodge(width = 0.8)) + # 绘制误差棒,与柱状图对齐 stat_summary(geom = "errorbar", fun.data = "mean_se", position = position_dodge(width = 0.8), width = 0.2) + # 自定义标签 labs(x = "问题主题", y = "回答得分", fill = "受访者") + theme_minimal()
效果说明
- 原输出问题:x轴为独立的问题文本,每个类别仅对应一类受访者,无法对比同主题的亲子回答。
- 修正后效果:x轴为统一的核心主题,每个主题下两个柱子紧邻排列,直接展示儿童与父母的回答差异,且无需手动处理40+问题的主题分组。
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

