如何在R语言中计算数据框各列响应值的占比?
问题:生成有序值占比的数据框
我有如下格式的数据:
User <-c('User_1','User_2','User_3','User_4','User_5') Q1 <- c('Never', 'Rarely', 'Sometimes', 'Often', 'Always') Q2<- c('Sometimes', 'Rarely', 'Sometimes', 'Often', 'Rarely') Q3 <- c('Always', 'Rarely', 'Sometimes', 'Always', 'Rarely') data1 <- data.frame(User, Q1, Q2, Q3) print(data1)
输出结果为:
User Q1 Q2 Q3 1 User_1 Never Sometimes Always 2 User_2 Rarely Rarely Rarely 3 User_3 Sometimes Sometimes Sometimes 4 User_4 Often Often Always 5 User_5 Always Rarely Rarely
我的目标是生成一个数据框,展示数据集中每个有序值的占比,预期结果如下:
Q1 Q2 Q3 Never 20% 0% 0% Rarely 20% 40% 40% Sometimes 20% 40% 20% Often 20% 20% 0% Always 20% 0% 40%
不知道该如何实现,恳请帮忙解决。
解决方案
可以通过两种方式实现,核心是按指定顺序统计各选项频次并转换为百分比格式:
方法一:基础R实现
# 定义有序选项的固定顺序,确保结果按预期排列 order_levels <- c("Never", "Rarely", "Sometimes", "Often", "Always") # 提取需要统计的问卷列,排除User列 q_cols <- data1[, -1] # 遍历每一列,统计占比并格式化 result <- lapply(q_cols, function(col) { # 强制按指定顺序统计,缺失选项自动补0 freq <- table(factor(col, levels = order_levels)) # 计算占比并格式化为百分比字符串 paste0(round((freq / sum(freq)) * 100, 0), "%") }) # 转换为数据框,设置行名为有序选项 result_df <- as.data.frame(result) rownames(result_df) <- order_levels print(result_df)
运行后输出与预期一致:
Q1 Q2 Q3 Never 20% 0% 0% Rarely 20% 40% 40% Sometimes 20% 40% 20% Often 20% 20% 0% Always 20% 0% 40%
方法二:tidyverse工具包实现(简洁风格)
如果习惯使用dplyr和tidyr,可以用tidy风格代码实现:
library(dplyr) library(tidyr) order_levels <- c("Never", "Rarely", "Sometimes", "Often", "Always") result_df <- data1 %>% # 转换为长格式,方便分组统计 pivot_longer(cols = -User, names_to = "Question", values_to = "Response") %>% # 按问题和响应分组,统计频次 count(Question, Response) %>% # 计算每个问题下各响应的占比 group_by(Question) %>% mutate(percentage = paste0(round((n / sum(n)) * 100, 0), "%")) %>% # 转换回宽格式,缺失选项补0% pivot_wider(names_from = Question, values_from = percentage, values_fill = "0%") %>% # 按指定顺序排列行 arrange(factor(Response, levels = order_levels)) %>% # 将响应列设为行名,移除原列 column_to_rownames("Response") print(result_df)
关键注意点
- 指定有序选项顺序:通过
factor()强制按设定的顺序统计,避免遗漏选项或打乱排列。 - 缺失值补0:两种方法都处理了未出现的选项,确保结果包含所有预期的有序值。
- 百分比格式化:用
paste0()将比例转换为带百分号的字符串,符合预期输出格式。
内容的提问来源于stack exchange,提问作者Socsi2
相关产品推荐
相关产品推荐

