【问题标题】:How to search a vector for a certain pattern如何在向量中搜索特定模式
【发布时间】:2014-11-08 16:29:08
【问题描述】:

我想要一个函数来搜索vector 的特定模式“1 后 4”(即“1”“4”)。它应该列出所有找到的序列和打印 为每个人提供口粮,他们的长度,从哪里开始和结束。

它应该在以下向量中搜索等于 N>=8 的向量的一部分,并记住这些条件:

1) 像这样的特定比例:

BigRatio= Number of (1,4)*N/(Number of (1)*Number of (4)) 
    has to be more or equal than 0.2 % 

2) 和(1,4)在向量中的比例(平均

 SmallRadtio= (Number of 1 + Number of 4)/(length of sequence) for 0.3%

如果满足条件,它应该打印每场比赛的口粮序列。

这是向量:

vector=c(1,1,1,1,1,1,1,4,4,4,4,2,3,1,1,1,1,1,1,1,4,4,4,4,2,3,1,4,1,4,1,4,1,4,1,4,
1,4,1,4,4,2,3,1,1,1,1,4,1,1,1,4,4,4,4,2,3,1,1,4,1,4,1,4,1,1,1,4,4,4,4,2,3,3,1,1,
4,1,4,1,4,1,1,1,4,4,4,4,4,4,4,4,2,3,1,1,1,1,1,1,1,4,4,1,1,4,2,1,1,1,1,1,1,4,3,
2,4,2,1,5,6,2,3,1,2,4,1,2,3,1,1,1,1,1,1,1,2,3,4,5,1,2,3,4,1,1,1,1,1,1,2,3,4,1,1,
1,2,3,1,2,3,1,2,3,4,3,1,2,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,
4,1,4,4,2,3,1,1,1,1,4,1,1,1,3,1,1,1,1,4,1,1,1,3,1,1,1,1,4,1,1,1,4,1,1,1,3,1,1,
1,1,4,2,3,1,1,4,1,4,1,4)

vector2=as.character(vector)

我将它转换为字符,因为我认为这样会更容易。我可能是 错了。

到目前为止我的代码/进度

我对此有两个想法:

1)该功能可以一次搜索8个或更多(我可以在功能中选择)数字,然后检查口粮。如果它是一个好的 8 个数字,然后提供有关它的信息。

2) 另一个想法是有一个评分系统,每对 5 分 1,4 和 -1 每隔一个数字。然后它应该以某种方式给出一个估计 这些部分在哪里并且应该找到这些段。第一个想法的问题是 可能会有一个部分有 40%,下一个部分有 20%,它们加起来可能不止这些。所以我试图弄清楚如何摆脱这个消极积极的陷阱。也许搜索系统应该检查每个数字或对 数量大于整个段。这更复杂,但又更精确。

使用代码,我被困住了如何制作该功能。我知道争论应该是 vector 和我想搜索的序列的所需长度(如果我去 第一个想法)。我想我必须使用for loop 来计算每个数字(或两个数字),以便我可以检查它们是否等于(1,4),然后“记住”它计算 该部分的长度。当然搜索其中的每个部分 1 ili 4 到 计算他们的口粮。

我想过使用这种循环:

for (i in 1:length(vector)) {
    idx <- agrep(vector[i],x)
    matches[i] <- length(vector)

但我认为这是错误的,并不完全正确。

我还是编程和 R 的新手。

补充问题:

如果将函数用于数据框,它会是什么样子?它会将搜索更改为指定行吗?是否可以将向量转换为数据框?

编辑:

另一个例子和说明:

sample2=c("aaaaabababababababababababababababcabcbababc bcbabcbcdddcbcbcdcbcbcbdcb
          bcbcbcbdbdbcbcbcbccbbcbbcbcbcbcbcbcbabababababababccbbcbbcbcbcbcbcbcbdbdbcbcbcbccb
          bcbcbcbdbdbcbcbcbccbbcbbcbcbcbcbcbbababababababababababababacbcbacbcbcdcbcbcbdcbbcdaddabcbac
          cabcbabcbabcbcbbabbabababababababababababa")

nchar(sample2)

所以这就是它应该做的:

1) 想法

  1. 搜索字符串的每 50 部分,即首先搜索该部分:

     "aaaaabababababababababababababababcabcbababcbcbabc"
    

然后是这部分(该字符串的下一个 50 个元素的序列)

  "bcbabcbcdddcbcbcdcbcbcbdcbbcbcbcbdbdbcbcbcbccbbcbb"

对于字符串的每隔 50 个元素到此为止。

如您所见,后 50 个元素中包含符合条件的“ba”。所以这将 不满足条件,不显示。

  1. 接下来是通过以下方式检查它是否满足正确的条件(例如 >0.5 口粮) 上面提到的公式针对某种模式,在这种情况下是“ba”。如果它的“ba”大于 >0.5 然后它应该打印出那个序列,比如它什么时候开始,返回口粮等等。 例如,这应该在数据框中。

下一个想法是计算该字符串中>0.5 的最佳分段是什么。这意味着 如果在 50 个元素的第一部分中有 0.4 个“ba”,就会出现问题,并且 在“ba”的下一个 50 0.1 中,就在该部分的开头: 想象中的前 50 个最后有很多 ba,但还不够:

   "aaaaabababababdcdcdcdacacbababababababababababababab"

接下来的50个有很多开头:

   "bababababababcbcdcbcbcbdcbbcbcbcbdbdbcbcbcbccbbcbbcd"

那么如何使它更优化呢?我们是否应该在上面解释“ba”的评分系统来找到 满足条件的段的最佳长度?

【问题讨论】:

  • 您的向量以1 1 1 1 1 1 1 4 4 4 4 开头。算一组还是第 7 位和第 8 位的1 4 是第 1 组?
  • 算作一组1 4
  • 看来vector中有44个元素满足这个条件
  • 还不够具体。你给出了一个向量,但你没有说正确的答案是什么。目前,可接受的运行长度 > 0.2% 的标准似乎可以接受任何运行。这是计划好的吗?
  • 目前还不清楚如何处理 1111144444 和 1414141414 这两种不同的情况。不同还是等价?

标签: r vector seq


【解决方案1】:

我很恼火的是,在生成有用的代码后仍然没有投票,而且问题似乎仍然模棱两可。新示例对其进行了换行,但不清楚我们应该将它们作为单独的行读取,因为:

> nchar(readLines(textConnection(sample2)))
[1]  71  92 102  52

将长字符值拆分成更小的部分并不难:

samp3 <- paste(rep("a", 300), collapse="")
mapply( substr, seq(1,nchar(samp3),by=50), seq(1,nchar(samp3),by=50)+49, MoreArgs=list(x=samp3))
[1] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[2] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[3] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[4] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[5] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[6] "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

如果你想在你的学术追求上取得进步,你需要努力以其他人可以执行的方式表达一个具体的例子。

------------第一次尝试:

这里有一些矢量化代码,应该可以生成执行此操作所需的工具。找到正确的向量化函数可以让您超越 SAS 和 BASIC 所培养的 for-loop 思维。循环在需要时很有用,但除非真的需要,否则 R 程序员通常会尽量避免使用它们。我不确定确切的期望结果是什么,但至少这应该可以推动对话:

# convert to single character item
collapsV <- paste0(vector,collapse="") 
pos14 <- gregexpr("14", collapsV)  # regex pattern matching
# look for runs of 2 differences , i.e. "14"'s next to each other
diff14_2 <- rle( diff(gregexpr("14", collapsV)[[1]]) ) 
#Run Length Encoding  ...# value is a two element list that looks like
#  lengths: int [1:22] 1 1 6 1 1 1 2 1 1 2 ...
#  values : int [1:22] 13 7 2 8 4 8 2 4 9 2 ...

which( diff14_2$values==2 & diff14_2$lengths>4)
[1]  3 16

因此,第三个 gregexpr“命中”将是第一个 14141414 运行的“向量”中至少 4 对长的位置。检查它:

> pos14[[1]][3]
[1] 27
> vector[27:40]
 [1] 1 4 1 4 1 4 1 4 1 4 1 4 1 4
> vector[25:40]
 [1] 2 3 1 4 1 4 1 4 1 4 1 4 1 4 1 4

而 16 是 gregexpr 值中的第二个位置,它指向“vector”中的位置:

> pos14[[1]][16]
[1] 76
> vector[76:(76+8)]
[1] 1 4 1 4 1 4 1 1 1

您应该打印出所有中间值以查看发生了什么。

【讨论】:

  • 我将进行编辑以详细说明我想用另一个示例做什么。
猜你喜欢
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多