如何将多列种族人口统计变量合并为单列并标记混血情况?
问题描述
我正在处理一份调查原始数据导出文件,目前处于数据清洗阶段。部分人口统计变量的结构不利于分析,具体来说,受访者可选择多个种族选项,数据导出后每个种族对应一列,选中的列填种族名称,未选的为NA。
复现数据集的R代码:
ID <- c(rep(c(1:8), 1)) White <- c("White",NA,NA,NA,NA,NA,"White","White") Asian <- c(NA,NA,NA,NA,NA,"Asian",NA,"Asian") SouthAfrican <- c(NA,"SouthAfrican",NA, NA,NA, NA, NA, "SouthAfrican") Hispanic <- c(NA, NA, NA, NA, "Hispanic", "Hispanic", NA, NA) WestAsian <- c(NA, NA, NA, NA, NA, NA, "WestAsian", NA) PreferNotToAnswer <- c(NA, NA,"PreferNotToAnswer", "PreferNotToAnswer", NA, NA, NA, NA) df <- data.frame(ID, White, Asian, SouthAfrican, Hispanic, WestAsian, PreferNotToAnswer)
我希望创建一个Race列,将各分散列中的值合并到该列中:
- 若受访者仅选择一个种族选项,直接填入该种族名称
- 若选择多个种族选项(如ID为8的受访者),则编码为“Mixed”
预期结果对应的R代码:
ID <- c(rep(c(1:8), 1)) White <- c("White",NA,NA,NA,NA,NA,"White","White") Asian <- c(NA,NA,NA,NA,NA,"Asian",NA,"Asian") SouthAfrican <- c(NA,"SouthAfrican",NA, NA,NA, NA, NA, "SouthAfrican") Hispanic <- c(NA, NA, NA, NA, "Hispanic", "Hispanic", NA, NA) WestAsian <- c(NA, NA, NA, NA, NA, NA, "WestAsian", NA) PreferNotToAnswer <- c(NA, NA,"PreferNotToAnswer", "PreferNotToAnswer",NA, NA, NA, NA) Race <- c("White","SouthAfrican","PreferNotToAnswer", "PreferNotToAnswer","Hispanic", "Mixed", "Mixed", "Mixed") df <- data.frame(ID, White, Asian, SouthAfrican, Hispanic,WestAsian,PreferNotToAnswer,Race)
解决方案
方法一:使用dplyr + tidyr(推荐,代码简洁易读)
library(dplyr) library(tidyr) df_updated <- df %>% rowwise() %>% mutate( # 收集当前行非NA的种族值 selected_races = list(na.omit(c_across(White:PreferNotToAnswer))), # 根据选中数量生成Race列 Race = case_when( length(selected_races) == 1 ~ selected_races[[1]], length(selected_races) > 1 ~ "Mixed" ) ) %>% ungroup() %>% select(-selected_races) # 删除临时辅助列
方法二:基础R实现(无需额外安装包)
# 逐行处理,生成Race列 df$Race <- apply(df[, -1], 1, function(row) { non_na_vals <- na.omit(row) if (length(non_na_vals) == 1) { non_na_vals[1] } else if (length(non_na_vals) > 1) { "Mixed" } else { NA # 处理未选择任何选项的情况(若存在) } })
结果验证
运行任意一种方法后,数据集的Race列将与预期结果完全匹配。
内容的提问来源于stack exchange,提问作者Darko
相关产品推荐
相关产品推荐

