在R中按性别统计非数值问卷数据并可视化的错误解决求助
问题与解决方案
问题背景
我有一个包含2787行、259列的样本数据,来自西班牙研究机构CIS开展的调查,旨在了解西班牙民众对当前与6个月前经济状况的感知。其中:
- P3列是分类变量,包含5个非数值选项:
"better"、"worse"、"same"、"don't know"、"don't answer" - P19列是二进制分类标识(
"1"代表男性,"2"代表女性),并非数值型数据
我希望统计不同性别群体中各经济状况感知选项的人数并绘制可视化图表,编写的代码如下:
CVSPastIndividualSituationMales<- aggregate(CIS$P3 ~ CIS$P19 == 1, CIS, sum) CVSPastSpainSituationFemales<- aggregate(CIS$P3 ~ CIS$P19 == 2, CIS, sum) CurrentVSPastIndividualSituationMales<-ggplot(CIS,mapping=aes(x=CVSPastIndividualSituationMales))+geom_bar(fill="LightGreen")+xlab("Current VS Past Individual Situation for Males") CurrentVSPastSpainSituationFemales <-ggplot(CIS,mapping=aes(CVSPastSpainSituationFemales))+geom_bar(fill="Green") + xlab("Current VS Past Spain Situation for Females") ggarrange(CurrentVSPastIndividualSituationMales, CurrentVSPastSpainSituationFemales, ncol = 1, nrow = 1)
运行代码后出现如下错误:
Error in Summary.factor(c(3L, 3L, 3L, 3L, 3L, 2L, 1L, 3L, 2L, 3L, 3L, : ‘sum’ not meaningful for factors
错误原因分析
- 分类变量误用数值函数:P3是分类(factor)类型,
sum函数仅适用于数值型数据,对分类变量求和无意义,这是报错的核心原因。 - 分组逻辑错误:
aggregate(CIS$P3 ~ CIS$P19 == 1, ...)的写法无法正确按性别分组统计P3各选项的数量,逻辑混乱。 - 绘图数据映射错误:ggplot代码直接使用原始数据集
CIS,而非统计好的分组结果,导致x轴映射无效。
正确实现方案
方法1:使用tidyverse工具链(dplyr + ggplot2)
代码清晰易读,适合分类数据的统计与可视化:
# 加载必要包 library(dplyr) library(ggplot2) library(ggpubr) # 1. 按性别和P3选项统计人数,并转换性别编码为易懂标签 gender_p3_stats <- CIS %>% mutate(gender = case_when( P19 == "1" ~ "男性", P19 == "2" ~ "女性" )) %>% group_by(gender, P3) %>% summarise(count = n(), .groups = "drop") # 2. 生成两个独立子图并合并 male_plot <- ggplot(filter(gender_p3_stats, gender == "男性"), aes(x = P3, y = count)) + geom_col(fill = "LightGreen") + labs(title = "男性群体经济状况感知", x = "", y = "人数") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) female_plot <- ggplot(filter(gender_p3_stats, gender == "女性"), aes(x = P3, y = count)) + geom_col(fill = "Green") + labs(title = "女性群体经济状况感知", x = "", y = "人数") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 合并子图 ggarrange(male_plot, female_plot, ncol = 2, nrow = 1)
方法2:使用基础R实现
无需加载tidyverse包,用基础R函数完成统计与绘图:
library(ggplot2) library(ggpubr) # 1. 生成性别与P3的交叉计数表,转换为数据框 cross_table <- table(CIS$P19, CIS$P3) cross_df <- as.data.frame(cross_table) colnames(cross_df) <- c("gender_code", "P3", "count") cross_df$gender <- ifelse(cross_df$gender_code == "1", "男性", "女性") # 2. 绘制子图并合并 male_plot <- ggplot(subset(cross_df, gender == "男性"), aes(x = P3, y = count)) + geom_col(fill = "LightGreen") + labs(title = "男性群体经济状况感知", x = "", y = "人数") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) female_plot <- ggplot(subset(cross_df, gender == "女性"), aes(x = P3, y = count)) + geom_col(fill = "Green") + labs(title = "女性群体经济状况感知", x = "", y = "人数") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) ggarrange(male_plot, female_plot, ncol = 2)
内容的提问来源于stack exchange,提问作者ArtUr693
相关产品推荐
相关产品推荐

