R中pivot_longer处理Likert数据时补全未选响应项计0的实现方法
Likert题分组统计补全零值选项方案
问题核心
- 数据集含多道分值规则不统一的Likert题(部分为1-5分制、部分为1-7分制),已通过
pivot_longer转换为长格式统计各响应选项的选择频次、占比 - 现有统计逻辑会自动过滤特定课程分组下无受访者选择的选项行,需要保留每个题项、每个课程分组下的全部合法响应选项,未被选中的选项计数
n=0、占比percent=0.00 - 已知缺失案例:A765课程的likert_1题缺失选项1,B768课程的likert_1题缺失选项2
实现逻辑
核心通过tidyr::complete()函数补全所有「课程-题项-合法分值」的组合,对不存在的组合填充零值;由于不同题项分值范围不统一,先单独维护题项-分值映射表,避免统一补全导致的分值范围错误。
可直接运行的代码
1. 加载依赖包
library(tidyverse)
2. 定义各题项的合法分值规则
根据你实际的题项分值设置修改下表参数即可,后续新增题项只需在表中追加对应行:
# 题项-分值映射表,示例规则:likert_1/likert_2为1-5分,likert_3/likert_4为1-7分 likert_rule <- tibble( item = c("likert_1", "likert_2", "likert_3", "likert_4"), score_min = c(1, 1, 1, 1), score_max = c(5, 5, 7, 7) ) %>% mutate(valid_score = map2(score_min, score_max, ~seq(.x, .y, by = 1))) %>% unnest(valid_score)
3. 从原始宽表d1生成完整统计结果
如果你还在数据处理初期,直接运行以下代码即可一步得到符合要求的结果:
d1_result <- d1 %>% # 宽表转长表,逻辑和你原有pivot_longer代码一致 pivot_longer( cols = starts_with("likert_"), names_to = "item", values_to = "score" ) %>% # 统计各课程、各题项、各分值的原始选择数 count(Course, item, score, name = "n") %>% # 按课程+题项分组,补全当前题项下所有合法分值 group_by(Course, item) %>% complete( score = likert_rule$valid_score[likert_rule$item == cur_group()$item], fill = list(n = 0) # 无选择的分值计数填0 ) %>% # 分组计算占比,保留两位小数 mutate(percent = round(n / sum(n) * 100, 2)) %>% ungroup()
4. 已有统计结果d1_long的补全方案
如果你已经生成了存在缺失行的d1_long统计结果,不需要从头处理原始数据,直接运行以下补全代码即可:
d1_fixed <- d1_long %>% group_by(Course, item) %>% complete( score = likert_rule$valid_score[likert_rule$item == cur_group()$item], fill = list(n = 0, percent = 0) ) %>% # 建议补全后重新计算占比,避免原有统计值的计算误差 mutate(percent = round(n / sum(n) * 100, 2)) %>% ungroup()
注意:必须保证
likert_rule中记录的题项名称、分值范围和你的实际问卷设置完全一致,否则会出现多余选项或者漏补选项的问题。
内容的提问来源于stack exchange,提问作者sdS
相关产品推荐
相关产品推荐

