如何基于二项分布计数数据绘制分组双向翻转条形图?
绘制参考样式的翻转条形图
要实现你描述的、参考Sevarika等人2022年研究的翻转条形图,我们可以用ggplot2结合数据预处理来完成。以下是完整的可运行代码和说明:
1. 数据准备与预处理
首先修正原始数据中sex列的长度问题(原代码中长度不匹配),然后统计不同性别下疼痛响应(0=无痛,1=疼痛)的患者数量:
# 加载所需包 library(ggplot2) library(dplyr) # 修正后的原始数据(sex列长度匹配其他变量) id <- c(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10) trt <- c("C","E","C","E","C","E","C","E","C","E","C","E","C","E","C","E","C","E","E","C") response <- c(0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1) sex <- c(rep("male", 10), rep("female", 10)) # 5名男性×2条记录=10行,同理女性 data <- data.frame(id, trt, response, sex) # 统计各分组的患者数(按id去重,避免重复计数) count_df <- data %>% group_by(sex, response) %>% summarise(patient_count = n_distinct(id), .groups = "drop") # 为女性组设置负数值,实现上下分栏的翻转效果 count_df <- count_df %>% mutate(patient_count = ifelse(sex == "female", -patient_count, patient_count))
2. 绘制目标条形图
ggplot(count_df, aes(x = factor(response), y = patient_count, fill = factor(response))) + # 绘制条形 geom_col(position = "dodge", width = 0.7) + # 按性别分上下展示,顶部男性、底部女性 facet_grid(sex ~ ., scales = "free_y", space = "free_y") + # 翻转坐标轴,实现横向条形 coord_flip() + # 设置标签与标题 labs( x = "疼痛响应", y = "患者数量", fill = "疼痛响应" ) + # 调整Y轴刻度,将负数转为正数显示 scale_y_continuous( breaks = seq(-max(abs(count_df$patient_count)), max(abs(count_df$patient_count)), 1), labels = abs(seq(-max(abs(count_df$patient_count)), max(abs(count_df$patient_count)), 1)) ) + # 自定义填充色(可根据参考图调整) scale_fill_manual(values = c("0" = "#3182bd", "1" = "#e6550d")) + # 优化主题样式 theme_minimal() + theme( strip.text.y = element_text(angle = 0, size = 11), # 性别标签水平显示 panel.grid.major.y = element_blank(), # 移除纵向网格线 legend.position = "top", # 图例移至顶部 axis.text = element_text(size = 10) )
关键细节说明
- 数据预处理:每个患者对应两条记录,因此用
n_distinct(id)统计真实患者数;给女性组的计数设为负数,是为了在分栏时让女性条形向下延伸,匹配“顶部男性、底部女性”的需求。 - 绘图设置:
facet_grid(sex ~ .)实现性别分组,coord_flip()将条形转为横向;Y轴刻度处理确保负数显示为正数,避免视觉混淆。
内容的提问来源于stack exchange,提问作者Miquel
相关产品推荐
相关产品推荐

