如何用R函数将含多选项的列拆分为布尔值新列?
批量将多选项列转换为布尔值列(R语言)
我有一个数据库,其中大量列包含选自选项集合的多个选项,需将这些列转换为True/False列以在PowerBI中分析。手动处理可行但列数和选项数太多,效率太低。
手动实现示例
# 查看barriers列的所有唯一选项 sort(unique(unlist(str_split(bound_wf$barriers, " AND ")))) # 手动生成布尔列 test <- bound_wf %>% mutate( barriers_brexit = grepl("Brexit", barriers), barriers_econ = grepl("Current economic climate", barriers) )
尝试自定义函数遇到的问题
我写了伪代码尝试批量处理,但无法正常运行,推测R未按预期读取参数:
function (column, separator = " AND ") # 获取选项列表 list <- sort(unique(unlist(str_split(bound_wf$column, separator)))) # 为每个选项生成布尔列 for item in list test <- bound_wf %>% mutate(column_item = grepl(item, column)
实际编写的函数运行时,list输出为bound_wf$barrier,没有得到预期的唯一选项列表:
widen <- function(column, separator){ column <- as.vector(column) separator <- as.vector(separator) df <- as.vector(str_c("bound_wf$", column)) # 获取选项列表 list <- sort(unique(unlist(str_split(df, separator)))) print(list) # 为每个选项生成布尔列 for (item in list) { test <- bound_wf %>% mutate(column_item = grepl(item, column)) } }
可复现数据集
df <- data.frame(id = 1:10,column = c("option one AND option three", "option three", "option one AND option two AND option three", "option one", "option two AND option three", "option one AND option four", "option two", "option one AND option two", "option three AND option four", "option one AND option two AND option four"))
解决方案
问题根源
- 用
str_c("bound_wf$", column)拼接字符串无法获取实际列数据,只是生成了一个文本字符串,导致str_split处理的是这个字符串而非列内容 - 循环中每次重新赋值
test,最终只会保留最后一个选项的布尔列 mutate中使用固定列名column_item,无法动态生成对应选项的列名
修正后的函数(基于tidyverse)
library(tidyverse) widen_multi_choice <- function(data, col_name, separator = " AND ") { # 提取并整理所有唯一选项 unique_options <- data %>% pull({{col_name}}) %>% str_split(separator) %>% unlist() %>% str_trim() %>% # 清理选项前后的空格 unique() %>% sort() # 批量生成布尔列 data %>% mutate( across( all_of(unique_options), ~grepl(str_c("\\b", .x, "\\b"), {{col_name}}, fixed = FALSE), .names = "{col_name}_{.col}" ) ) } # 测试函数 result <- widen_multi_choice(df, column, " AND ") print(result)
关键说明
- 使用
{{col_name}}实现非标准评估,直接引用传入的列名,无需拼接字符串 str_trim避免因选项前后空格导致的重复选项across批量处理所有唯一选项,.names参数自动生成原列名_选项名格式的列名\\b是单词边界,避免部分匹配(比如防止"option one"匹配"option one two"),不需要的话可以移除
内容的提问来源于stack exchange,提问作者Lulu
相关产品推荐
相关产品推荐

