R语言:按诊断分组计算测试题均值并绘制分组柱状图
问题解决:按诊断分组计算测试题均值并绘制组间差异柱状图
原始数据
首先构造并展示原始数据框:
ID <- c("a", "b", "c", "d", "e") age <- c(22, 34, 55, 55, 45) gender <- c("female", "male", "female", "female", "male") diagnosis <- c(1, 2, 2, 1, 1) A1 <- c(4,5,12,45,33) A2 <- c(12,15,46,34,56) A3 <- c(23,33,45,66,32) mydf <- data.frame(ID, age, gender, diagnosis, A1, A2, A3) mydf
| ID | age | gender | diagnosis | A1 | A2 | A3 |
|---|---|---|---|---|---|---|
| a | 22 | female | 1 | 4 | 12 | 23 |
| b | 34 | male | 2 | 5 | 15 | 33 |
| c | 55 | female | 2 | 12 | 46 | 45 |
| d | 55 | female | 1 | 45 | 34 | 66 |
| e | 45 | male | 1 | 33 | 56 | 32 |
问题与错误尝试
需求为按diagnosis分组计算A1、A2、A3的均值,并绘制组间差异柱状图。用户尝试通过以下代码添加均值行,但非测试题列被错误填充了均值:
mydf <- rbind(mydf, "mean" = round(colMeans(mydf[,5:7], na.rm = TRUE), 2)) mydf
错误结果示例:
| ID | age | gender | diagnosis | A1 | A2 | A3 |
|---|---|---|---|---|---|---|
| a | 22.0 | female | 1 | 4.0 | 12.0 | 23.0 |
| b | 34.0 | male | 2 | 5.0 | 15.0 | 33.0 |
| c | 55.0 | female | 2 | 12.0 | 46.0 | 45.0 |
| d | 55.0 | female | 1 | 45.0 | 34.0 | 66.0 |
| e | 45.0 | male | 1 | 33.0 | 56.0 | 32.0 |
| 19.8 | 32.6 | 39.8 | 19.8 | 32.6 | 39.8 | 19.8 |
错误原因
rbind要求新增行的列数与原数据框完全匹配。用户仅计算了A1-A3的均值(长度为3的向量),rbind会自动循环填充该向量到所有7列,导致非测试题列被错误赋值。
解决方案
1. 正确计算分组均值
方法1:使用dplyr包(推荐)
library(dplyr) # 按diagnosis分组,计算A1-A3的均值并保留2位小数 group_means <- mydf %>% group_by(diagnosis) %>% summarise(across(A1:A3, ~round(mean(.), 2))) group_means
输出结果:
| diagnosis | A1 | A2 | A3 |
|---|---|---|---|
| 1 | 27.33 | 34.0 | 40.33 |
| 2 | 8.5 | 30.5 | 39.0 |
方法2:基础R实现
# 用aggregate函数分组计算均值 group_means_base <- aggregate(cbind(A1, A2, A3) ~ diagnosis, data = mydf, FUN = function(x) round(mean(x), 2))
2. 绘制组间差异柱状图
使用ggplot2绘制分组并列柱状图,需先将数据转换为长格式:
library(ggplot2) library(tidyr) # 转换为长格式数据,适配ggplot2绘图 long_data <- group_means %>% pivot_longer(cols = A1:A3, names_to = "test_item", values_to = "mean_score") # 绘制柱状图 ggplot(long_data, aes(x = test_item, y = mean_score, fill = factor(diagnosis))) + geom_col(position = position_dodge(width = 0.8), width = 0.7) + labs(title = "不同诊断组测试题得分均值", x = "测试题", y = "均值得分", fill = "诊断分组") + theme_minimal() + scale_fill_manual(values = c("#1f77b4", "#ff7f0e"), labels = c("患病", "未患病")) + geom_text(aes(label = mean_score), position = position_dodge(width = 0.8), vjust = -0.5, size = 3.5)
该代码会生成并列分组柱状图,每个测试题对应两个柱子(诊断1和2),柱子上方标注均值,清晰展示组间得分差异。
内容的提问来源于stack exchange,提问作者dplyr
相关产品推荐
相关产品推荐

