R语言多列种族编码变量合并为单列的报错问题求解
问题原因&解决方法
报错原因
你的所有hhm1_race开头的列都是字符型(从dput输出可见取值都带双引号),sum()函数无法直接对字符型数值做计算,所以触发类型错误。
现有代码快速修复
只需要在处理前先把所有目标列转为整数型即可:
NewRace %>% # 先把所有种族列转成整数型 mutate(across(starts_with("hhm1_race"), ~as.integer(.x))) %>% mutate( new_race = as.integer(apply(across(starts_with("hhm1_race")), 1, which.max)), new_race_sum = apply(across(starts_with("hhm1_race")), 1, function(x) sum(x, na.rm = TRUE)), new_race = case_when( new_race_sum == 0 ~ NA_integer_, new_race_sum == 1 ~ new_race, new_race_sum > 1 ~ 99L ) ) %>% select(-new_race_sum)
更优实现思路
用dplyr原生的行向操作替代apply,语法更统一,性能也更好,适配两种常见的编码逻辑:
方案1:直接读取列内存储的编码值
如果你的列内已经存储了对应种族的编码(如你提供的样例数据中,非0值已经是1/2/3/6等目标编码),用这个方案:
library(dplyr) NewRace %>% # 转换所有种族列为整数 mutate(across(starts_with("hhm1_race"), as.integer)) %>% rowwise() %>% mutate( # 提取当前行所有非0的种族编码 vals = list(c_across(starts_with("hhm1_race"))[which(c_across(starts_with("hhm1_race")) != 0)]), # 按规则赋值:无选中→NA、单选中→对应编码、多选中→99 new_race = case_when( length(vals) == 0 ~ NA_integer_, length(vals) == 1 ~ vals[[1]], length(vals) > 1 ~ 99L ) ) %>% ungroup() %>% select(-vals)
方案2:按列名映射编码(更稳妥)
如果列内只有0/1两种值,选中为1、未选中为0,需要自己指定列对应的种族编码,用这个方案,逻辑更可控:
library(dplyr) # 先定义列名和种族编码的映射关系,可按需修改 race_map <- c( "hhm1_race___1" = 1, # 白人 "hhm1_race___2" = 2, # 黑人 "hhm1_race___hispanic" = 3, # 西班牙裔 "hhm1_race___3" = 4, "hhm1_race___4" = 5, "hhm1_race___5" = 6 ) NewRace %>% rowwise() %>% mutate( # 提取当前行值为"1"的列名 selected_col = list(names(which(c_across(starts_with("hhm1_race")) == "1"))), new_race = case_when( length(selected_col) == 0 ~ NA_integer_, length(selected_col) == 1 ~ race_map[selected_col[[1]]], length(selected_col) > 1 ~ 99L ) ) %>% ungroup() %>% select(-selected_col)
内容的提问来源于stack exchange,提问作者lziegs
相关产品推荐
相关产品推荐

