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
假设我有一个长序列和一个查询序列:
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