R字符串操作:将分号分隔的分类列转换为0-1哑变量矩阵
R 实现方案
以下提供两种可直接运行的实现方式,均满足全部需求:
方案1:基础R实现(无需安装额外依赖包)
# 构造原始数据集 fruits <- data.frame( Fruits = c( "Apples; Oranges; Bananas", "Plums; Apples", "Satsumas; Plums", "Apricots/Peaches; Avocados", "Avocados; Oranges" ), stringsAsFactors = FALSE ) # 按分号+任意数量空格分割字符串,自动去除水果名前后空格 split_fruits <- strsplit(fruits$Fruits, ";\\s*") # 提取所有唯一水果名 all_unique_fruits <- unique(unlist(split_fruits)) # 逐行匹配是否包含对应水果,生成0/1矩阵 result_matrix <- t(sapply(split_fruits, function(row_fruits) { as.integer(all_unique_fruits %in% row_fruits) })) # 转换为数据框,check.names=FALSE禁止自动将/替换为点 result_df <- as.data.frame( result_matrix, col.names = all_unique_fruits, check.names = FALSE )
方案2:tidyverse 实现(语法更简洁易维护)
library(dplyr) library(tidyr) library(stringr) result_df <- fruits %>% # 增加行索引用于后续宽表转换 mutate(row_id = row_number(), # 分割字符串并自动去空格 fruit_item = str_split(Fruits, ";\\s*")) %>% unnest(fruit_item) %>% # 标记出现过的水果为1 mutate(val = 1) %>% # 转换为宽表,不修改特殊列名 pivot_wider( id_cols = row_id, names_from = fruit_item, values_from = val, values_fill = 0, names_repair = "minimal" ) %>% # 可选:删除辅助用的行索引列 select(-row_id)
关键逻辑说明
- 分割字符串时使用正则
;\\s*作为分隔符,自动匹配分号后的任意数量空格,直接消除水果名前后的空格差异 - 转换为数据框/宽表时关闭列名校验,保留
/字符不被自动替换为. - 匹配逻辑自动按是否存在填充1/0,无需额外判断
内容的提问来源于stack exchange,提问作者Cinnamon
相关产品推荐
相关产品推荐

