在R中按诊断分组为多列生成带百分比的饼图
解决方案
1. 准备环境与数据
首先加载所需R包,同时构造示例数据:
# 加载tidyverse套件(包含数据处理和绘图工具) library(tidyverse) # 构造示例数据 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("A", "B", "C", NA, "E") A2 <- c("D", "E", "B", "A", "D") A3 <- c("B", NA, "A", "B", "B") mydf <- data.frame(ID, age, gender, diagnosis, A1, A2, A3)
2. 计算分组百分比频率
将宽格式数据转为长格式,过滤缺失值后,按diagnosis(分组)和测试问题计算各答案的占比:
freq_df <- mydf %>% # 把A1/A2/A3转为长格式,保留诊断分组信息 pivot_longer(cols = starts_with("A"), names_to = "question", values_to = "answer") %>% # 移除答案为缺失值的行 drop_na(answer) %>% # 按诊断、问题、答案分组统计数量 group_by(diagnosis, question, answer) %>% summarise(count = n(), .groups = "drop_last") %>% # 计算每个问题-诊断组内的百分比 mutate(percentage = count / sum(count) * 100, # 生成饼图显示的标签(答案+百分比) label = paste0(answer, "\n", round(percentage, 1), "%"))
3. 批量生成并排饼图
用ggplot2绘制饼图,通过分面实现每个测试问题对应两组饼图(确诊/未确诊)并排展示:
ggplot(freq_df, aes(x = "", y = percentage, fill = answer)) + # 绘制基础柱状图,后续转为饼图 geom_bar(stat = "identity", width = 1) + # 转换为极坐标,形成饼图效果 coord_polar("y", start = 0) + # 添加百分比标签,居中显示在饼块内 geom_text(aes(label = label), position = position_stack(vjust = 0.5)) + # 按问题+诊断分面,实现每个问题的两组饼图横向并排 facet_grid(. ~ question + diagnosis, labeller = labeller(diagnosis = c("1" = "确诊", "2" = "未确诊"))) + # 移除冗余的坐标轴和网格线 theme_void() + # 设置填充色的图例标题 labs(fill = "答案") + # 调整分面标题的样式 theme(strip.text = element_text(size = 12, face = "bold"))
说明
- 代码通过
pivot_longer批量处理所有以"A"开头的测试问题,无需逐个编写处理逻辑 - 分面参数确保每个问题的确诊/未确诊组饼图横向并排展示
- 自动忽略缺失值,计算每个答案在对应分组内的占比并标注在饼图中
内容的提问来源于stack exchange,提问作者dplyr
相关产品推荐
相关产品推荐

