如何在R中将单列分类变量转换为0-1编码的多列?
解决重复分类列的独热编码问题
你遇到的问题是spread()的典型限制:它要求每个(分组键,分类值)的组合必须唯一,而你的数据中同一个type对应多行,所以无法直接使用。下面是几种可行的解决方案,都能帮你把分类列转换为0/1编码的多列:
方法1:用tidyr::pivot_wider(推荐,替代spread)
pivot_wider是spread的升级版,专门处理这类有重复键的场景,通过values_fill参数指定缺失值的填充值:
library(dplyr) library(tidyr) a <- tibble(type=c("A", "A", "B", "B", "C", "D")) a %>% mutate(dat = 1) %>% # 添加标记列 pivot_wider( names_from = type, # 用type的值作为新列名 values_from = dat, # 用dat的值填充新列 values_fill = 0 # 缺失的位置填充0 )
运行结果就是你想要的:
#> # A tibble: 6 × 4 #> A B C D #> <dbl> <dbl> <dbl> <dbl> #> 1 1 0 0 0 #> 2 1 0 0 0 #> 3 0 1 0 0 #> 4 0 1 0 0 #> 5 0 0 1 0 #> 6 0 0 0 1
方法2:用dplyr::across直接生成列
不需要额外的标记列,直接通过across遍历所有唯一分类值,生成对应的0/1列:
a %>% mutate(across(unique(type), ~ifelse(type == .x, 1, 0)))
这个方法更简洁,一步生成所有目标列,原type列会保留,如果不需要可以加上select(-type)移除。
方法3:基础R的model.matrix
如果不想加载太多包,基础R的model.matrix可以快速生成独热编码,再转换为tibble:
model.matrix(~ type - 1, data = a) %>% as_tibble() %>% rename_with(~gsub("type", "", .x)) # 去掉列名中的"type"前缀
方法4:用fastDummies包一键生成
如果经常需要做独热编码,fastDummies包的dummy_cols函数可以自动处理,非常方便:
library(fastDummies) a %>% dummy_cols( select_columns = "type", # 指定要编码的列 remove_selected_columns = TRUE # 移除原type列 )
以上几种方法都能实现你想要的效果,其中方法1和方法2最贴合你已经在使用的tidyverse工具链。
内容的提问来源于stack exchange,提问作者costebk08
相关产品推荐
相关产品推荐

