You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

REDCap多选复选框数据导入R Studio后的自动化合并需求

自动化合并REDCap导出的多选复选框变量(以种族变量为例)

问题背景

从REDCap导出数据到R Studio时,多选复选框类型的问题会被拆分为多个独立变量——比如支持多选的种族问题,导出后会变成8个单独变量。之前只能靠手动编写R代码合并(示例如下),不仅耗时,还要做大量质量检查,尝试过REDCapR包也没找到可行方案。

手动合并代码示例:

cleandata <- data %>% 
  mutate(race_cat = rowSums(data[,85:92]),    
        new_race = case_when(race_cat == 1 & race___5 == 1 & ethnicity != 1 ~ "White",
                             race_cat == 1 & race___2 == 1 & ethnicity != 1 ~ "Asian",
                             race_cat == 1 & race___3 == 1 & ethnicity != 1 ~ "Black",
                             race_cat == 1 & race___7 == 1 & ethnicity != 1 ~ "Other",
                             race_cat == 1 & race___1 == 1 & ethnicity != 1 ~ "AIAN",
                             race_cat == 1 & race___4 == 1 & ethnicity != 1 ~ "NHPI",
                             race_cat == 1 & race___8 == 1 & ethnicity != 1 ~ "Unknown",
                             race_cat == 1 & race___6 == 1 & ethnicity != 1 ~ "Multi-Racial",
                             race_cat == 0 & ethnicity != 1 ~ "Unknown",
                             ethnicity == 1 ~ "Hispanic",
                             race_cat > 1 ~ "Multi-Racial"))
  table(cleandata$new_race)

自动化解决方案

方法一:基于变量前缀批量匹配+选项映射

利用REDCap导出变量的命名规律(比如race___1、race___2这种格式),批量筛选变量并建立选项映射,无需手动指定列位置,代码更易维护。

library(tidyverse)

# 1. 筛选所有以"race___"开头的种族多选变量
race_vars <- str_subset(names(data), "^race___")

# 2. 批量处理每行选中的种族选项,生成合并后的分类
data <- data %>%
  rowwise() %>%
  # 标记当前行选中的种族变量
  mutate(selected_races = list(race_vars[which(c_across(all_of(race_vars)) == 1)])) %>%
  ungroup() %>%
  # 把选中的变量名映射为对应的种族名称
  mutate(selected_race_names = map_chr(selected_races, function(selected) {
    if (length(selected) == 0) return("Unknown")
    # 建立变量名到种族名称的映射表
    name_mapping <- c(
      "race___1" = "AIAN",
      "race___2" = "Asian",
      "race___3" = "Black",
      "race___4" = "NHPI",
      "race___5" = "White",
      "race___6" = "Multi-Racial",
      "race___7" = "Other",
      "race___8" = "Unknown"
    )
    # 多选直接返回"Multi-Racial",单选返回对应名称
    selected_names <- name_mapping[selected]
    if (length(selected_names) > 1) return("Multi-Racial")
    return(selected_names)
  })) %>%
  # 结合ethnicity变量调整最终分类(西班牙裔优先)
  mutate(new_race = case_when(
    ethnicity == 1 ~ "Hispanic",
    TRUE ~ selected_race_names
  ))

# 查看合并后的结果分布
table(data$new_race)

优势:不用手动指定列的位置(比如原代码中的85:92),只要REDCap的变量命名规则不变,就能自动适配;映射表统一管理,新增或修改选项时只需调整name_mapping,无需逐行修改判断逻辑。

方法二:简化手动判断逻辑(批量生成条件)

如果习惯用原代码的rowSums思路,可以通过批量生成判断条件减少重复代码:

library(tidyverse)

data <- data %>%
  # 计算每行选中的种族选项数量
  mutate(race_cat = rowSums(select(., starts_with("race___")))) %>%
  # 批量生成单个种族的判断条件
  mutate(
    AIAN = if_else(race_cat == 1 & race___1 == 1 & ethnicity != 1, "AIAN", NA_character_),
    Asian = if_else(race_cat == 1 & race___2 == 1 & ethnicity != 1, "Asian", NA_character_),
    Black = if_else(race_cat == 1 & race___3 == 1 & ethnicity != 1, "Black", NA_character_),
    NHPI = if_else(race_cat == 1 & race___4 == 1 & ethnicity != 1, "NHPI", NA_character_),
    White = if_else(race_cat == 1 & race___5 == 1 & ethnicity != 1, "White", NA_character_),
    Other = if_else(race_cat == 1 & race___7 == 1 & ethnicity != 1, "Other", NA_character_),
    Unknown_race = if_else((race_cat == 0 & ethnicity != 1) | (race_cat == 1 & race___8 == 1 & ethnicity != 1), "Unknown", NA_character_)
  ) %>%
  # 合并非NA的种族值,多选直接标记为Multi-Racial
  rowwise() %>%
  mutate(selected_race = coalesce(AIAN, Asian, Black, NHPI, White, Other, Unknown_race)) %>%
  ungroup() %>%
  mutate(new_race = case_when(
    ethnicity == 1 ~ "Hispanic",
    race_cat > 1 ~ "Multi-Racial",
    TRUE ~ selected_race
  )) %>%
  # 清理中间变量
  select(-c(AIAN, Asian, Black, NHPI, White, Other, Unknown_race, selected_race))

# 查看结果
table(data$new_race)

优势:保留了原代码的逻辑,但通过批量生成条件减少了重复的case_when语句,降低出错概率。


内容的提问来源于stack exchange,提问作者Alex Toups

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:30:00