R语言中如何将非互斥哑变量转换为带组合类别的单分类变量?
哑变量拼接为非互斥分类变量的实现方案
基础R原生方案(适配已有apply使用习惯)
你之前用apply逐行统计哑变量和的思路完全可以复用,只需要把逐行的计算逻辑从“求和”替换为“提取值为1的列名并拼接”,无需额外加载第三方包。
# 指定需要转换的哑变量列 dummy_cols <- c("a", "b", "c") # 逐行生成拼接结果 df$z <- apply(df[dummy_cols], 1, function(row) { # 筛选当前行值为1的列名 matched_vars <- names(row)[row == 1] # 无匹配(所有哑变量为0)则返回0,否则用逗号拼接 if (length(matched_vars) == 0) return(0) paste(matched_vars, collapse = ",") })
Tidyverse 方案(适配日常数据清洗流程)
适合已加载dplyr做数据处理的场景,代码逻辑更直观,不需要手动写循环判断:
library(dplyr) df <- df %>% rowwise() %>% mutate(z = { # 获取当前行选中哑变量的取值 var_vals <- c_across(all_of(dummy_cols)) # 筛选值为1的列名 matched_vars <- names(var_vals)[var_vals == 1] if (length(matched_vars) == 0) 0 else paste(matched_vars, collapse = ",") }) %>% ungroup()
大数据量高效方案
当数据集行数达到十万级以上时,逐行循环的运行速度会明显下降,可以通过矩阵运算替代逐行逻辑,大幅提升处理效率:
# 将哑变量列转为数值矩阵 dummy_mat <- as.matrix(df[dummy_cols]) # 构造对角矩阵,将每个列位置替换为对应列名加逗号 name_diag <- diag(paste0(dummy_cols, ",")) # 矩阵乘法计算每行的拼接内容 combo_mat <- dummy_mat %*% name_diag # 去掉每行末尾多余的逗号 df$z <- trimws( apply(combo_mat, 1, paste, collapse = ""), which = "right", whitespace = "," ) # 将全空行(所有哑变量为0)替换为0 df$z[df$z == ""] <- 0
注意:拼接结果的顺序严格遵循你指定的
dummy_cols列顺序,调整这个向量内的列排列即可修改拼接顺序。如果需要将最终生成的z列转为标准分类因子,直接执行df$z <- as.factor(df$z)即可,所有出现过的拼接组合会自动成为因子水平。
内容的提问来源于stack exchange,提问作者Electrino
相关产品推荐
相关产品推荐

