R语言如何将问卷多选对应的195个二分变量批量合并为单选变量
解决方案
方法1:dplyr行遍历实现(逻辑直观易理解)
无需手动编写195行判断逻辑,直接通过行匹配实现对应取值:
library(tidyverse) # charvec为提前准备好的选项文本向量,示例:charvec <- paste0("option", 1:195) df <- df %>% rowwise() %>% mutate( newvar = { # 匹配所有var开头的目标变量,取当前行的所有值 vals <- c_across(matches("^var\\d+$")) # 正则匹配避免误选其他var开头的变量 # 取第一个为yes的位置,对应选项文本 charvec[which(vals == "yes")[1]] } ) %>% ungroup() # 取消行分组,避免影响后续数据操作
方法2:矩阵匹配实现(速度更快,适合大样本)
通过矩阵运算直接定位选中位置,运算效率远高于循环方案:
library(tidyverse) # 提取所有目标变量转为yes/no的逻辑矩阵 var_mat <- df %>% select(matches("^var\\d+$")) == "yes" # 取每行第一个yes的列位置,ties.method指定多选时取第一个选项 idx <- max.col(var_mat, ties.method = "first") # 直接映射为对应选项 df$newvar <- charvec[idx]
可直接调用的封装函数
修正你原有函数的语法问题后,封装好的可直接调用版本如下:
multichoice_to_one <- function(df, pat, charvec) { library(tidyverse) # 构造目标变量名列表 var_cols <- str_c(pat, seq_along(charvec)) # 矩阵定位选中位置 var_mat <- df %>% select(all_of(var_cols)) == "yes" idx <- max.col(var_mat, ties.method = "first") df$newvar <- charvec[idx] return(df) } # 调用示例 # charvec <- paste0("option", 1:195) # df <- multichoice_to_one(df, pat = "var", charvec = charvec)
注意事项
- 若存在受访者未选择任何选项的情况,生成的
newvar会对应返回NA,可根据业务需求替换为"未作答"等自定义取值 - 若存在受访者选择多个选项的情况,上述代码默认取第一个匹配的选项,如需单独标记多选样本,可新增统计每行选中数量的字段进行判断:
df <- df %>% mutate( select_count = rowSums(select(., matches("^var\\d+$")) == "yes"), newvar = ifelse(select_count > 1, "多选", newvar) )
内容的提问来源于stack exchange,提问作者ohebie
相关产品推荐
相关产品推荐

