跨多列检测关键词并生成标记列的R语言技术实现问题
R语言关键词检测与新列生成解决方案
问题背景
给定数据框与关键词向量,需检测每行中各关键词是否存在于任意列,并为每个关键词生成0/1标记列:
数据定义:
set.seed(123) df <- data.frame( v1 = sample(LETTERS[1:10], 5), v2 = sample(LETTERS[1:10], 5), v3 = sample(LETTERS[1:10], 5), v4 = sample(LETTERS[1:10], 5) ) keys <- c("A", "C", "F", "H")
用户尝试for循环实现但生成NA列,代码及错误结果:
library(stringr) for(i in keys){ df[i] <- +str_detect(apply(df, 1, paste0, collapse = " "), keys[i]) } df # v1 v2 v3 v4 A C F H # 1 C A J I NA NA NA NA # 2 H E E C NA NA NA NA # 3 D H F A NA NA NA NA # 4 G D I J NA NA NA NA # 5 F C A F NA NA NA NA
但单独处理单个关键词逻辑可行:
+str_detect(apply(df, 1, paste0, collapse = " "), keys[1]) # [1] 1 0 1 0 1
解决方案
1. 修改原for循环
问题根源:循环中i已直接是关键词(如"A"),无需再用keys[i]索引,直接使用i即可。优化后代码:
library(stringr) # 提前拼接每行字符串,避免重复计算 row_combined <- apply(df, 1, paste0, collapse = " ") for(key in keys){ df[[key]] <- +str_detect(row_combined, key) } # 输出结果 df
运行后正确结果:
v1 v2 v3 v4 A C F H 1 C A J I 1 1 0 0 2 H E E C 0 1 0 1 3 D H F A 1 0 1 1 4 G D I J 0 0 0 0 5 F C A F 1 1 1 0
2. dplyr + purrr 简洁实现
采用tidyverse风格,无需拼接字符串,直接逐行检测:
library(dplyr) library(purrr) df <- df %>% bind_cols( map_dfc(keys, ~tibble(!!.x := +(rowSums(df == .x) > 0))) )
或用across函数更紧凑:
df <- df %>% mutate( across(all_of(keys), ~+rowSums(select(cur_data(), v1:v4) == .x) > 0) )
3. 基础R向量化解法
利用矩阵运算高效实现,适合大数据场景:
# 生成关键词标记矩阵 key_flags <- sapply(keys, function(k) +(rowSums(df == k) > 0)) # 合并到原数据框 df <- cbind(df, key_flags)
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

