如何用tidyverse语法移除字符串变量间的重叠文本?
解决方案:用tidyverse移除文本重叠内容
可以通过自定义文本处理函数,结合dplyr::across批量处理后续变量,实现需求。以下是具体实现:
1. 定义重叠移除函数
先编写一个处理单组文本的函数,逻辑如下:
- 若任一输入为
NA,直接返回目标变量 - 将
original按空格拆分单词,转义正则特殊字符后构建匹配规则 - 从目标变量中替换掉匹配到的重叠单词
- 压缩多余空格,若结果为空则返回
NA
library(tidyverse) remove_overlap <- function(orig, target) { if (is.na(orig) || is.na(target)) { return(target) } # 拆分original的单词并转义正则特殊字符 orig_words <- str_split(orig, "\\s+")[[1]] orig_words_escaped <- str_replace_all(orig_words, "([\\.\\?\\!\\(\\)\\[\\]\\{\\}\\\\^\\$\\*\\+\\-\\|\\&\\~\\<\\>])", "\\\\\\1") # 构建完整词匹配的正则模式 pattern <- str_c("\\b(", str_c(orig_words_escaped, collapse = "|"), ")\\b") # 替换重叠内容并清理空格 result <- target %>% str_replace_all(pattern, "") %>% str_squish() # 空内容转为NA if (result == "") NA_character_ else result }
2. 批量处理数据框
用across批量处理vec2、vec3等后续变量,调用自定义函数完成重叠内容移除:
df_in <- tibble( original=c('This is my sentence', 'Americans spell it summarise', "This one uses double quote.", NA_character_), vec2=c('This is my sentence', 'Americans spell it summarize', "A completely new one.", NA_character_), vec3=c("Now it's a new string", 'Americans spell it summarise', NA_character_, 'Here is a new one')) df_out <- df_in %>% mutate(across(c(vec2, vec3), ~remove_overlap(original, .x)))
验证结果
运行后df_out与期望输出完全一致:
# 查看输出 df_out #> # A tibble: 4 × 3 #> original vec2 vec3 #> <chr> <chr> <chr> #> 1 This is my sentence <NA> Now it's a new string #> 2 Americans spell it summarise summarize <NA> #> 3 This one uses double quote. A completely new . <NA> #> 4 <NA> <NA> Here is a new one
补充说明
- 函数使用
\\b(词边界)确保只匹配完整单词,避免部分字符的误匹配 - 转义正则特殊字符(如
.、?),避免这些字符被当作正则语法解析 - 用
str_squish清理替换后产生的多余空格,保证输出格式整洁
内容的提问来源于stack exchange,提问作者JRR
相关产品推荐
相关产品推荐

