假设我有一个很长的序列和一个查询序列:
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
包中是否有更有效的方法。
答案 0 :(得分:2)
将长序列转换为矩阵:
LongSeqMx <- as.matrix(
data.frame(p1 = LongSeq[1:(length(LongSeq) - 2)],
p2 = LongSeq[2:(length(LongSeq) - 1)],
p3 = LongSeq[3:(length(LongSeq))]))
然后,您可以应用k-nearest-neighbor算法:
FNN::get.knnx(LongSeqMx, matrix(QuerySeq, nrow = 1))
此示例将索引和欧几里德距离返回到最近的10个点。
答案 1 :(得分:2)
以下使用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