R,字串,变异我认为-多个字符串中的多个部分字符串替换

问题描述

我是文本挖掘,R和整洁方法的新手,并且正在寻找同类建议,以克服对从pdf文件读取的文本字符串进行预处理的障碍。具体的问题是用多个字符串替换多个字符串。

我有2个来源的数据:

  1. PDF报告:我已经使用map和pdf_text函数将pdf报告的目录读取到一个数据框中,该目录创建了一个包含3列的标题:page_string,filename和pagenumber。有1,191个条目,page_string包含一个字符串,是pdf文本的一页。
  2. 专业词汇和替换词的CSV文件:我已使用read_CSV函数导入此文件。结果df有2列,其中有77个条目:target_vocab(例如,社会工作者)和replace_token(例如,social_worker)。

我的目标是修改主数据框中的当前字符串,在进行标记化之前,将与target_vocab中的专业单词匹配的字符串替换为replace_token中的相关复合标记。

字符串示例-字符串替换前后:

  1. “社会工作者和早期帮助人员与多机构合作伙伴一起制定由分配的社会工作者领导的有需要的儿童计划。”
  2. “社会工作者和早期帮助人员与多机构合作伙伴一起制定由分配的社会工作者领导的CIN计划。”

很显然,我希望将“社会工作者”,“早期帮助”,“多机构”,“有需要的孩子”和“社会工作者”替换为复合令牌。

我的代码:

#a bank of pdf reports and "professional_words.csv" in current working directory

library(tidyverse)
library(pdftools)
#> Using poppler version 0.73.0
library(tidytext)
library(stringr)

pdf_filenames <- list.files(pattern = "pdf$")

words_df <- read_csv("professional_words.csv",skip = 1,col_names = c("target_vocab","replace_token"))

pattern_vector <- words_df$target_vocab
replacement_vector <- words_df$replace_token 

pdf_pages_df <- map_df(pdf_filenames,~ tibble(page_string = pdf_text(.x)) %>%
         mutate(filename = .x,pagenumber = row_number()) %>%
           mutate(page_string = str_replace_all(page_string,pattern_vector,replace_vector))) 

在地图功能中不起作用的位是:

mutate(page_string = str_replace_all(page_string,replace_vector)))

我尝试了各种变体,包括gsub,将其从管道分离到单独的map函数等。但是由于我的有限知识,我没有修复它。

我一直有警告:

在stri_replace_all_regex中(字符串,模式, fix_replacement(replacement),:较长的对象长度不是 较短的物体长度的倍数

使用这种代码变体,我还会收到错误消息:

mutate()输入page_string的问题。 x输入 page_string无法回收为10号。ℹ输入page_stringstr_replace_all(page_string,pattern = pattern_vector,replacement = replace_vector)。 {输入page_string的大小必须为10或1,而不是77。

我的感觉是map或list函数将对我有帮助,但是我似乎正在绕圈而行,我还没有找到能够帮助我解决问题的Stack Overflow响应。

解决方法

有一种方法可以处理str_replace_all中的stringr。与其提供patternreplacement,而是将命名向量传递给pattern。类似于pattern = c("social worker" = social_worker","early help" = "early_help","multi agency" = "multi_agency")。我将从一个简单的示例开始,然后向您展示如何R从您的words_df构建该命名向量。

# Simple example
library(stringr)
string <- "The quick brown fox"
str_replace_all(string,pattern = c("brown" = "green","fox" = "badger"))
[1] "The quick green badger"

在这里,您用R构建了一些命名的替换向量来处理一些看起来像您的假数据。

# Making the fake data
words_df <- data.frame(target = c("fox","brown","quick"),replacement = c("badger","green","versatile"))

strings_df <- data.frame(page_string = c("The quick brown fox","The sad yellow fox","The quick old dog","The lazy brown dog","The quick happy fox"))

# Making the named replacement vector from words_df
replacements <- c(words_df$replacement)
names(replacements) <- c(words_df$target)

# Doing the replacement
library(dplyr)
strings_df %>% 
  mutate(new_string = str_replace_all(page_string,pattern = replacements))

# The output
          page_string                 new_string
1 The quick brown fox The versatile green badger
2  The sad yellow fox      The sad yellow badger
3   The quick old dog      The versatile old dog
4  The lazy brown dog         The lazy green dog
5 The quick happy fox The versatile happy badger
,

str_replace_all不能那样工作。如果提供patternreplacement的向量,则第一个模式/替换将应用于string的第一个元素,依此类推。请参见以下示例:

library(stringr)

fruits <- c("one apple two","two pears","three bananas")
pattern_v <- c("one","two","three")
replace_v <- c("1","2","3")
str_replace_all(fruits,pattern_v,replace_v)
#> [1] "1 apple two" "2 pears"     "3 bananas"

reprex package(v0.3.0)于2020-08-25创建

请注意,在string的第二个元素中,“ two”仅被替换为“ 2”。因此,如果pattern / replacement向量的长度不等于string的长度(或倍数),则无效:

pattern_v <- c("one","two")
replace_v <- c("1","2")
str_replace_all(fruits,replace_v)
[1] "1 apple two"   "2 pears"       "three bananas"
warning:
In stri_replace_all_regex(string,pattern,fix_replacement(replacement),:
  longer object length is not a multiple of shorter object length

为避免此问题,可以为pattern传递命名向量:

str_replace_all(fruits,c("one" = "1","two" = "2","three" = "3"))
[1] "1 apple 2" "2 pears"   "3 bananas"

Ben的答案给出了一种使向量的创建变得容易的好方法:

pattern_new <- c("one","three")
names(pattern_new) <- c("1",pattern_new)
[1] "one apple two" "two pears"     "three bananas"
,

得益于快速的响应,问题得以解决,下面的工作代码可以解决我将来可能遇到的麻烦的问题:

professional_terms <- c(words_df$replace_token)
names(professional_terms) <- c(words_df$target_words) 
pdf_pages_df <- map_df(pdf_filenames,~ tibble(page_string = pdf_text(.x)) %>%
mutate(filename = .x,pagenumber = row_number(),page_string = str_replace_all(page_string,pattern = professional_terms)))

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...