如何用tidyverse的mutate与across基于字符向量生成二进制变量
问题:基于技能向量为招聘要求数据框生成二进制列
问题描述
现有存储招聘要求的data.frame(df)和技能字符向量(skills),需要为每个技能创建二进制列:若招聘要求包含对应技能则赋值为TRUE,否则为FALSE,要求使用tidy风格(mutate+across)实现。
示例数据
df = structure(list(id = c(582L, 582L, 582L, 582L, 582L), requirements = c("rpg; as400; sql; db2; java; aws", "python; sql; r; linux; sas; aws", "oracle; microsoft sql server; mysql", "uml; bmpn; sql", ".net; c#; python; mvvm; java")), class = "data.frame", row.names = c(NA, -5L)) skills = c("sql", "python", "aws", "java", "oracle")
期望输出
# id requirements sql python aws java oracle # 1 582 rpg; as400; sql; db2; java; aws TRUE FALSE TRUE TRUE FALSE # 2 582 python; sql; r; linux; sas; aws TRUE TRUE TRUE FALSE FALSE # 3 582 oracle; microsoft sql server; mysql TRUE FALSE FALSE FALSE TRUE # 4 582 uml; bmpn; sql TRUE FALSE FALSE FALSE FALSE # 5 582 .net; c#; python; mvvm; java FALSE TRUE FALSE TRUE FALSE
问题分析
你之前的代码中,colnames(.x)无法正确获取当前列名——因为across中的.x指代的是当前列的值而非列名,需要改用cur_column()函数来获取当前处理的列名。
正确实现方案
无需预先创建空列,直接在mutate中用across遍历技能向量,结合cur_column()和grepl完成匹配:
library(dplyr) df_processed <- df %>% mutate(across(all_of(skills), ~ grepl(cur_column(), requirements, fixed = TRUE)))
补充说明
all_of(skills):指定要生成的列(以技能向量中的元素作为列名)cur_column():获取当前正在处理的列名,即对应的技能名称fixed = TRUE:关闭正则表达式匹配,避免技能名中的特殊字符(如.)被当作正则符号处理,确保精确匹配目标字符串grepl直接返回逻辑值,无需额外用ifelse转换
如果需要更严谨的独立单词匹配(避免匹配包含目标技能的更长字符串,比如防止sql误匹配sqlserver),可以使用单词边界正则:
df_processed <- df %>% mutate(across(all_of(skills), ~ grepl(paste0("\\b", cur_column(), "\\b"), requirements)))
内容的提问来源于stack exchange,提问作者Jeparov
相关产品推荐
相关产品推荐

