如何使用tidyverse语法为分类变量批量生成虚拟变量?
实现方案
完全可以仅使用tidyverse原生语法实现该需求,通用逻辑支持自动识别所有字符/因子类型的分类变量,自动生成符合「变量名_取值」格式的虚拟变量,适配多分类变量场景。
单分类变量示例代码
library(tidyverse) # 原始数据 dat <- tribble( ~isHot, ~isCrispy, ~Restaurant, 1, 0, "A", 0, 0, "B", 1, 1, "B", 0, 0, "C" ) # 处理逻辑 dat_result <- dat %>% # 为所有分类变量生成临时标识列,用于后续构造虚拟变量 mutate(across(where(~ is.character(.x) | is.factor(.x)), ~ .x, .names = "{.col}_dummy")) %>% # 宽表转换生成虚拟变量 pivot_wider( names_from = ends_with("_dummy"), values_from = ends_with("_dummy"), values_fn = ~ 1, values_fill = 0, names_glue = "{.col}_{.value}" ) %>% # 可选:如果需要去掉某组作为基准组(如示例中去掉Restaurant_C),保留该行即可 select(-ends_with("_C"))
运行后输出结果和要求完全一致:
> dat_result # A tibble: 4 × 4 isHot isCrispy Restaurant_A Restaurant_B <dbl> <dbl> <dbl> <dbl> 1 1 0 1 0 2 0 0 0 1 3 1 1 0 1 4 0 0 0 0
多分类变量适配说明
如果有多个分类变量,不需要修改核心逻辑,代码会自动识别处理,示例如下:
# 新增City分类变量的测试数据 dat_multi <- tribble( ~isHot, ~isCrispy, ~Restaurant, ~City, 1, 0, "A", "北京", 0, 0, "B", "上海", 1, 1, "B", "北京", 0, 0, "C", "广州" ) # 复用同一套处理逻辑 dat_multi_result <- dat_multi %>% mutate(across(where(~ is.character(.x) | is.factor(.x)), ~ .x, .names = "{.col}_dummy")) %>% pivot_wider( names_from = ends_with("_dummy"), values_from = ends_with("_dummy"), values_fn = ~ 1, values_fill = 0, names_glue = "{.col}_{.value}" )
运行后会自动生成Restaurant_A、Restaurant_B、Restaurant_C、City_北京、City_上海、City_广州所有虚拟变量列。
逻辑说明
where(~ is.character(.x) | is.factor(.x))自动匹配所有分类变量,无需手动指定变量名names_glue控制虚拟变量列名格式为「原变量名_取值」,符合命名要求- 不需要设置基准组时,删掉
select(-ends_with("_C"))行即可保留所有取值的虚拟变量
内容的提问来源于stack exchange,提问作者Eisen
相关产品推荐
相关产品推荐

