ggplot2按因子水平绘比例而非计数及特定变量NA处理问题
解决方案:绘制组内比例并处理NA与自定义颜色
这里有几个针对性的修改,完美解决你的三个核心需求——在不删除全表NA的前提下过滤特定变量的缺失值、展示var1分组内var2各水平的比例,以及自定义Left/Right的颜色:
方法一:用ggplot原生语法直接实现(简洁版)
library(ggplot2) library(scales) # 用于百分比格式转换 # 你的示例数据 var1 <- c("Left", "Right", NA, "Left", "Right", "Right", "Right", "Left", "Left", "Right", "Left", "Left","Left", "Right", "Left", "Right", "Right", "Right", "Left", "Left", "Right", NA, "Left", "Left","Left", "Right", NA, "Left", "Right", "Right", "Right", "Left", "Left", "Right", "Left", "Left","Left", "Right", "Left", "Right", "Right", "Right", "Left", "Left", "Right", NA, "Left", "Left") var2 <- c("Higher", "Lower", NA, "Slightly higher", "Slightly higher", "Slightly higher", "Lower", "Slightly higher", "Higher", "Higher", "Higher", "Slightly higher","Higher", "Lower", "Slightly higher", "Slightly higher", "Slightly higher", "Lower", "Slightly higher", "Higher", "Higher", "Higher", NA, "Slightly lower","Higher", "Lower", NA, "Slightly higher", "Slightly higher", "Slightly higher", "Lower", "Slightly higher", "Higher", "Higher", "Higher", "Slightly higher","Higher", "Lower", "Slightly higher", "Slightly higher", "Slightly higher", "Lower", "Slightly lower", "Higher", "Higher", "Higher", NA, "Slightly lower") df <- as.data.frame(cbind(var1, var2)) # 修改后的绘图代码 Plot <- ggplot(df[!is.na(df$var1) & !is.na(df$var2), ], # 仅过滤var1和var2的NA aes(x = var2, y = after_stat(prop), group = var1)) + geom_bar(aes(fill = var1), position = "dodge") + labs(x = "Var2 水平", y = "组内比例", fill = "选择方向:") + # 可根据需求修改标签 scale_fill_manual(values = c("Left" = "#0072B2", "Right" = "#D55E00")) + # 自定义颜色,替换成你需要的 scale_y_continuous(labels = percent_format()) + # 将比例转为百分比显示 theme_classic() + theme(legend.position = "top") Plot
关键修改点说明
过滤特定变量的NA:
直接在ggplot的数据源中用df[!is.na(df$var1) & !is.na(df$var2), ],只排除var1或var2为NA的行,不会影响数据框中其他列的记录,避免了na.omit导致的大量数据丢失。绘制组内比例而非计数:
- 通过
y = after_stat(prop)让ggplot自动计算比例,配合group = var1指定分组依据,确保比例是每个var1组内的占比(比如Left组中选Higher的人数/Left组总人数)。 - 用
scale_y_continuous(labels = percent_format())把小数比例转换成百分比格式,可读性更强(需要提前加载scales包,没装的话先运行install.packages("scales"))。
- 通过
自定义颜色:
替换原来的scale_fill_discrete为scale_fill_manual,通过values参数给Left和Right指定专属颜色,你可以替换成任意十六进制颜色码或R内置颜色名称。
方法二:提前用dplyr预处理数据(更灵活)
如果需要对比例做更多自定义计算,推荐先预处理数据,再绘图:
library(ggplot2) library(dplyr) library(scales) df_summary <- df %>% filter(!is.na(var1), !is.na(var2)) %>% # 过滤目标变量的NA count(var1, var2) %>% # 计算每组的计数 group_by(var1) %>% mutate(prop = n / sum(n)) # 计算组内比例 ggplot(df_summary, aes(x = var2, y = prop, fill = var1)) + geom_col(position = "dodge") + labs(x = "Var2 水平", y = "组内比例", fill = "选择方向:") + scale_fill_manual(values = c("Left" = "#0072B2", "Right" = "#D55E00")) + scale_y_continuous(labels = percent_format()) + theme_classic() + theme(legend.position = "top")
这种方式更适合后续需要对统计结果做进一步分析的场景。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

