R语言ggplot:aes()内过滤数据报错,分性别柱状图绘制求助
ggplot2绘图:aes内过滤数据失效原因及解决方法
一、为什么你的代码会报错?
ggplot2的aes()函数核心是建立数据列与图形属性(x轴、y轴、颜色等)的映射关系,它要求传入的是数据框中已有的列名,而非filter()/select()这类数据处理函数。你写的代码存在几个关键问题:
- 每个美学参数(x、y、fill)传入的是不同筛选后的子数据,数据维度不匹配,ggplot无法将零散的向量对应起来;
- 存在拼写错误:表格列名为
Gender,代码里写的是gender;不存在Q列,应该是Response; position="dodge"是geom_col()的参数,不该放在aes()内部。
二、正确的数据过滤/绘图方法
方法1:提前整理数据(最推荐)
先用dplyr处理好数据,再传给ggplot绘图,逻辑更清晰:
library(dplyr) library(ggplot2) # 构造你的示例数据 df <- data.frame( Response = c(1,1,2,2,3,3), Gender = c(1,2,1,2,1,2), n = c(84,79,42,74,84,79) ) # 场景1:按性别汇总总回答数,X轴为两个性别 summary_data <- df %>% group_by(Gender) %>% summarise(total_n = sum(n)) ggplot(summary_data, aes(x = factor(Gender), y = total_n)) + geom_col(fill = c("#4285F4", "#EA4335")) + labs(x = "性别", y = "总回答数量") # 场景2:每个回答选项下展示不同性别的数量(分组柱状图) ggplot(df, aes(x = factor(Response), y = n, fill = factor(Gender))) + geom_col(position = "dodge") + labs(x = "回答选项", y = "数量", fill = "性别")
方法2:在图层内指定过滤后的数据
如果只需要绘制部分数据,可在geom_col()的data参数里直接传入筛选后的子集,无需改动原数据:
# 仅绘制性别1的数据 ggplot(df) + geom_col(data = filter(df, Gender == 1), aes(x = "性别1", y = n), fill = "#4285F4") + labs(x = "", y = "数量") # 同时绘制两个性别(不推荐,不如用fill映射更简洁) ggplot(df) + geom_col(data = filter(df, Gender == 1), aes(x = "性别1", y = n), fill = "#4285F4", width = 0.4) + geom_col(data = filter(df, Gender == 2), aes(x = "性别2", y = n), fill = "#EA4335", width = 0.4) + labs(x = "性别", y = "数量")
方法3:转宽格式后绘图
用tidyr把长格式数据转成宽格式,再分别映射不同列:
library(tidyr) wide_df <- df %>% pivot_wider(names_from = Gender, values_from = n, names_prefix = "性别") ggplot(wide_df, aes(x = factor(Response))) + geom_col(aes(y = 性别1), fill = "#4285F4", position = "dodge") + geom_col(aes(y = 性别2), fill = "#EA4335", position = "dodge") + labs(x = "回答选项", y = "数量")
内容的提问来源于stack exchange,提问作者Lefiek
相关产品推荐
相关产品推荐

