宽格式数据转列频率计数:优雅转换受试者数据为问题-频率数据框问询
优雅批量转换问卷响应频率数据框的方案
这个问题我太有共鸣了!之前用plyr逐个处理问题再rbind合并确实繁琐到爆炸,用tidyverse的dplyr+tidyr组合拳就能完美解决,全程批量操作,完全不用手动逐个处理问题,代码简洁还易维护。
先假设你的原始数据结构(宽格式)
通常问卷数据会是宽格式:每一列对应一个问题,每个单元格是受试者的响应选项(比如1-5分),示例数据如下:
library(tidyverse) # 构造模拟数据,3个问题,100个受试者的响应 set.seed(123) raw_df <- tibble( 问题A = sample(1:5, 100, replace = TRUE), 问题B = sample(1:5, 100, replace = TRUE), 问题C = sample(1:5, 100, replace = TRUE) )
核心处理代码(一行管道搞定)
freq_df <- raw_df %>% # 第一步:把宽格式转成长格式,所有问题的响应统一放到一列 pivot_longer(cols = everything(), names_to = "问题", values_to = "响应") %>% # 第二步:按问题+响应分组,统计每个组合的频率 count(问题, 响应) %>% # 第三步:把响应值转成列,缺失的频率填充为0(避免某个问题无某选项时出现NA) pivot_wider(names_from = "响应", values_from = "n", values_fill = 0) %>% # 可选:把列名从数字改成更直观的"选项1"格式 rename_with(~ paste0("选项", .), matches("^[1-5]$")) # 查看结果 print(freq_df)
代码逐段解释
pivot_longer:把原本分散在各列的问题,统一转成"问题"和"响应"两列,这一步是批量处理的关键——所有问题的响应都进入同一数据流,不用再逐个单独处理。count:替代plyr::count,自动按问题和响应分组统计频率,一次搞定所有问题的计数。pivot_wider:把响应值(1-5)转成列,values_fill=0确保如果某个问题没有某选项的响应,会填充0而不是NA,保证数据框结构完整。rename_with:可选操作,把列名从"1""2"改成"选项1""选项2",让结果更易读。
优势对比
和你之前的方法比,这个方案:
- 不需要逐个处理问题,不管你有10个还是100个问题,代码完全不用改
- 不需要手动
rbind合并结果,全程管道操作,数据流转清晰 - 自动处理缺失的响应选项(填充0),避免后续分析出问题
如果你的原始数据已经是长格式(比如每行是一个受试者的一个问题响应),那直接从count步骤开始就行,跳过pivot_longer。
内容的提问来源于stack exchange,提问作者Anne
相关产品推荐
相关产品推荐

