R:使用for循环查找另一个字符串旁边的特定字符串

问题描述 投票:1回答:1

我在单个向量中有一本小说的文本,它被单词novel.vector.words拆分我正在寻找字符串“血液”的所有实例。但是,由于向量是按字分割的,因此每个单词都是自己的字符串,我不知道在向量中搜索相邻的字符串。

我对循环的作用有基本的了解,并遵循教科书中的一些说明,我可以使用这个循环来定位“血液”的所有位置及其周围的上下文,以创建一个标签描绘的KWIC显示(关键词)在上下文中)。

node.positions <- grep("blood", novel.vector.words)

output.conc <- "D:/School/U Alberta/Classes/Winter 2019/LING 603/dracula_conc.txt"
cat("LEFT CONTEXT\tNODE\tRIGHT CONTEXT\n", file=output.conc) # tab-delimited header

#This establishes the range of how many words we can see in our KWIC display
context <- 10 # specify a window of ten words before and after the match

for (i in 1:length(node.positions)){ # access each match...
  # access the current match
  node <- novel.vector.words[node.positions[i]]
  # access the left context of the current match
  left.context <- novel.vector.words[(node.positions[i]-context):(node.positions[i]-1)]
  # access the right context of the current match
  right.context <- novel.vector.words[(node.positions[i]+1):(node.positions[i]+context)]
  # concatenate and print the results
  cat(left.context,"\t", node, "\t", right.context, "\n", file=output.conc, append=TRUE)}

然而,我不知道怎么做,就是使用像if语句之类的东西,只捕获“血”后跟“of”的实例。我是否需要for循环中的另一个变量?我想要它做的基本上是它找到的每一个“血液”实例,我想看看紧接着它的那个词是“of”。我希望循环找到所有这些实例并告诉我载体中有多少实例。

r for-loop corpus
1个回答
1
投票

您可以使用dplyr::lead创建一个索引,以匹配'blood'之后的'of':

library(dplyr)

novel.vector.words <- c("blood", "of", "blood", "red", "blood", "of", "blue", "blood")

which(grepl("blood", novel.vector.words) & grepl("of", lead(novel.vector.words)))

[1] 1 5

回答评论中的问题:

这当然可以通过基于循环的方法来完成,但是当已经有更好的设计和优化的包来完成文本挖掘任务中的繁重工作时,重新发明轮子几乎没有意义。

这里有一个例子,说明如何使用tidytext包找到Bram Stoker's Dracula中“血”和“of”之间出现的频率。

library(tidytext)
library(dplyr)
library(stringr)

## Read Dracula into dataframe and add explicit line numbers
fulltext <- data.frame(text=readLines("https://www.gutenberg.org/ebooks/345.txt.utf-8", encoding = "UTF-8"), stringsAsFactors = FALSE) %>%
  mutate(line = row_number())

## Pair of words to search for and word distance
word1 <- "blood"
word2 <- "of"
word_distance <- 5

## Create ngrams using skip_ngrams token
blood_of <- fulltext %>% 
  unnest_tokens(output = ngram, input = text,  token = "skip_ngrams", n = 2, k = word_distance - 1) %>%
  filter(str_detect(ngram, paste0("\\b", word1, "\\b")) & str_detect(ngram, paste0("\\b", word2, "\\b"))) 

## Return count
blood_of %>%
  nrow

[1] 54

## Inspect first six line number indices
head(blood_of$line)

[1]  999 1279 1309 2192 3844 4135
© www.soinside.com 2019 - 2024. All rights reserved.