有序距离内的最远元素,用于排序矢量

时间:2014-10-21 08:50:26

标签: r vector

我们有一个已排序的向量foo,对于每个元素i,我们希望找到最大的j foo[j]-foo[i] < 10。例如

foo <- c(1,2,5,7,13,17,25,33,85)

答案是:

bar <- c(4,4,5,5,6,7,8,8,9)

(对于i=1,自j以来最大的foo[4]-foo[1]=7-1<10为4。因此bar的第一项是4)。

我们可以使用barfor循环轻松计算while。但我正在寻找一个有效的代码R.任何想法?

3 个答案:

答案 0 :(得分:3)

使用非equi连接更新解决方案:

最近,非equi 加入在current development version of data.table, v1.9.7中实施。使用此功能非常简单:

require(data.table) # v1.9.7+
dt1 = data.table(x=foo)
dt2 = data.table(y=foo+10L)
dt1[dt2, on=.(x < y), mult="last", which=TRUE]
# [1] 4 4 5 5 6 7 8 8 9

在100,000个元素上,这比foverlaps

更快
set.seed(45L)
foo <- sort(sample(1e6, 1e5, FALSE))
dt1 = data.table(x=foo)
dt2 = data.table(y=foo+10L)
system.time(ans <- dt1[dt2, on=.(x < y), mult="last", which=TRUE])
#    user  system elapsed 
#   0.011   0.001   0.011 

请注意,此操作可以直接完成,如下所示:

ans <- data.table(x=foo)[.(y=x+10L), on=.(x < y), mult="last", which=TRUE]

使用foverlaps的旧方法:

这是一种可能更好地扩展的方法。使用foverlaps()版本1.9.4中的重叠范围连接函数data.table

require(data.table) ## 1.9.4+
x = data.table(start=foo, end=foo+9L)
lookup = data.table(start=foo, end=foo)
setkey(lookup) ## order doesn't change, as 'foo' is already sorted
foverlaps(x, lookup, mult="last", which=TRUE)
# [1] 4 4 5 5 6 7 8 8 9

计时100,000个数字:

set.seed(45L)
foo <- sort(sample(1e6, 1e5, FALSE))
arun <- function(foo) {
    x = data.table(start=foo, end=foo+9L)
    lookup = data.table(start=foo, end=foo)
    setkey(lookup)
    foverlaps(x, lookup, mult="last", which=TRUE)
}
system.time(arun(foo))
#    user  system elapsed 
#  0.142   0.009   0.153 

答案 1 :(得分:1)

尝试

 sapply(foo, function(x) {m1 <-foo-x; which.max(m1[m1<10])})
 #[1] 4 4 5 5 6 7 8 8 9

答案 2 :(得分:1)

假设没有NA值:

apply(as.matrix(dist(foo)), 1, function(x) {
  which.max(cumsum(x < 10))  
  })
#1 2 3 4 5 6 7 8 9 
#4 4 5 5 6 7 8 8 9 

这是一个仅使用稀疏矩阵的解决方案:

library(spam)
res <- apply.spam(as.spam(dist(foo)), 2, function(x) {
  test <- cumsum(x < 10)
  if (sum(test) > 0 ) which.max(test) else (0)
  }) + seq_along(foo)
res[length(res)] <- length(res)
#[1] 4 4 5 5 6 7 8 8 9
相关问题