R:在长序列上滑动查询

R: sliding a query overy a long sequence

假设我有一个长序列和一个查询序列:

LongSeq <- c(3,5,2,6,5,4,8,9,6,2,4,6,1,3,6,9,5,10,9,6,3,7,8,2)
QuerySeq <- c(6,2,4)

目标是使用例如欧氏距离从 LongSeq 中找到与 QuerySeq 具有相同或相似序列的子序列。写了一个 for 循环,一次滑动一步并计算欧几里得距离,但这很慢,尤其是当 LongSeq 真的很长时。我想知道在 R 或合适的 R 包中是否有更有效的方法来执行此操作。

将长序列转化为矩阵:

LongSeqMx <- as.matrix(
  data.frame(p1 = LongSeq[1:(length(LongSeq) - 2)],
             p2 = LongSeq[2:(length(LongSeq) - 1)],
             p3 = LongSeq[3:(length(LongSeq))]))

然后,你可以应用k-最近邻算法:

FNN::get.knnx(LongSeqMx, matrix(QuerySeq, nrow = 1))

此示例returns 到 10 个最近点的索引和欧几里得距离。

下面在zoo包中使用了rollapply

library(zoo)

dist <- function(x, y) sqrt(sum((x-y)^2))

w <- length(QuerySeq)
dists <- rollapply(LongSeq, w, dist, y = QuerySeq, fill = Inf, align = "left")

least.ix <- seq(which.min(dists), length = w)
least.seq <- LongSeq[least.ix]
least.dist <- dist(least.seq, QuerySeq)

给予:

> least.ix
[1] 9 10 11
> least.dist
[1] 0
> least.seq
[1] 6 2 4