首页 > 解决方案 > 使用 R 根据子字符串的第 n 次出现有效地分解字符串

问题描述

介绍

给定 R 中的一个字符串,是否有可能得到一个向量化的解决方案(即没有循环),我们可以将字符串分成块,其中每个块由字符串中第 n 次出现的子字符串决定。

使用可重现示例完成的工作

假设我们有几段著名的 Lorem Ipsum 文本。

library(strex)
# devtools::install_github("aakosm/lipsum")
library(lipsum)

my.string = capture.output(lipsum(5))
my.string = paste(my.string, collapse = " ")

> my.string # (partial output)
# [1] "Lorem ipsum dolor ... id est laborum. "

我们希望在单词“in”的每3 次出现时将该文本分成多个段(包含一个空格是为了与包含“in”作为其中一部分的单词区分开来,例如“min”)。

我有以下带有while循环的解决方案:

# We wish to break up the string at every 
# 3rd occurence of the worn "in"

break.character = " in"
break.occurrence = 3
string.list = list()
i = 1

# initialize string to send into the loop
current.string = my.string

while(length(current.string) > 0){

  # Enter segment into the list which occurs BEFORE nth occurence character of interest
  string.list[[i]] = str_before_nth(current.string, break.character, break.occurrence)

  # Update next string to exmine.
  # Next string to examine is current string AFTER nth occurence of character of interest
  current.string = str_after_nth(current.string, break.character, break.occurrence)

  i = i + 1
}

我们能够在带有警告的列表中获得所需的输出(未显示警告)

> string.list (#partial output shown)
[[1]]
[1] "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit"

[[2]]
[1] " voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor"
...

[[6]]
[1] " voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor"

目标

是否可以通过矢量化(即使用 、 等)来改进此apply()解决lapply()方案mapply()。此外,我当前的解决方案切断了块中子字符串的最后一次出现。

当前的解决方案可能不适用于极长的字符串(例如我们正在寻找第 n 次出现核苷酸子串的块的 DNA 序列)。

标签: rstringtexttext-miningpattern-mining

解决方案


试试这个:

text_split=strsplit(text," in ")[[1]]

l=length(text_split)
n = floor(l/3)
Seq = seq(1,by=2,length.out = n)

L= list()
L=sapply(Seq, function(x){
  paste0(paste(text_split[x:(x+2)],collapse=" in ")," in ")
})
if (l>(n*3)){
L = c(L,paste(text_split[(n*3+1):l],collapse=" in "))
}

最后一个条件是在数字in不能被 3 整除的情况下。另外,最后in粘贴的那个sapply()是在那里,因为我不知道你想用in分隔你的块的那个做什么。


推荐阅读