使用dplyr在R中将非互斥种族类别转换为互斥类别
问题
需要将非互斥的种族类别哑变量重新编码为互斥类别,要求用tidyverse的dplyr实现(已有baseR参考方案):
- 数据里
White、Black、Asian是0-1哑变量,1代表勾选对应种族,0代表没选 - 要创建新变量
RaceCount:- 勾选超过1个种族 → 标记为
Multiracial - 只勾选1个 → 直接用对应的种族名称
- 勾选超过1个种族 → 标记为
- 之前试了这段代码但结果不对:
df <- df %>% group_by(White, Asian, Black) %>% mutate(RaceCount = n())
- 期望的输出示例:
ID White Black Asian RaceCount 1 1 0 0 White 2 1 0 0 White 3 1 0 0 White 4 1 0 1 Multiracial 5 1 0 1 Multiracial 6 0 0 1 Asian 7 0 1 0 Black 8 0 1 0 Black 9 1 0 0 White 10 0 1 0 Black
解决方案
用dplyr的行处理+条件判断就能搞定,这里给两种实现方式:
方式1:按行处理(直观易懂)
library(tidyverse) df <- df %>% rowwise() %>% # 开启逐行计算模式 mutate( # 计算当前行勾选的种族数量 race_num = sum(c_across(White:Asian)), # 根据规则生成RaceCount RaceCount = case_when( race_num > 1 ~ "Multiracial", White == 1 ~ "White", Black == 1 ~ "Black", Asian == 1 ~ "Asian", # 处理全未勾选的边缘情况,不需要可删除 TRUE ~ "Unknown" ) ) %>% ungroup() %>% # 取消行分组,避免影响后续操作 select(-race_num) # 删掉临时变量,可选
方式2:用rowSums(更高效,适合大数据)
如果数据量较大,rowwise()效率偏低,换成rowSums()更快捷:
df <- df %>% mutate( race_num = rowSums(select(., White:Asian)), RaceCount = case_when( race_num > 1 ~ "Multiracial", White == 1 ~ "White", Black == 1 ~ "Black", Asian == 1 ~ "Asian", TRUE ~ "Unknown" ) ) %>% select(-race_num)
之前代码异常的原因
你之前的group_by(...) %>% mutate(RaceCount = n())逻辑是统计同一种族组合的行数,比如三个全0的组有多少条数据,而非判断当前行勾选的种族数量,结果自然不符合需求。
内容的提问来源于stack exchange,提问作者Reap409
相关产品推荐
相关产品推荐

