快速查找元素索引的方法

时间:2015-10-15 14:03:04

标签: arrays r vector

我有一个酉段[0,1]和几个点,由向量v表示。此外,我有一个介于0和1之间的数字k,我想知道该数字落入的区间索引是什么。 我想知道是否存在一种聪明的方式而不是循环元素。

k <- 0.67 
v <- c( 0.12 , 0.25 , 0.48 , 0.78 , 1)

3 个答案:

答案 0 :(得分:2)

以下是一种方法:

间隔是向量v(n)的长度的n-1。因此,考虑到这一点,您可以使用Position返回第一次出现function(x) 0.67 < x的位置:

#sort helps in case v is not sorted
Position(function(x) 0.67 < sort(x), v) - 1
[1] 3

上述事件的位置为4,间隔为第3。

答案 1 :(得分:1)

我一直在研究一些非常相似的东西,除了它会向量舍入到最接近的值而不是返回索引。我一直在用Rcpp编写c ++脚本。下面我对上面的三个解决方案以及我编写的cpp脚本进行基准测试,它返回值而不是索引,但很容易修改。如果您不计算cpp代码,library(Rcpp) cppFunction('NumericVector nearest_neighbor(NumericVector x, NumericVector v) { int n, m, i, j, k, adj; n = v.size(); m = x.size(); NumericVector y(m); for (int a=0;a<m;a++) { if (x[a] < v[0]) { return v[0]; } else if (x[a] >= v[n-1]) { return v[n-1]; } i = 0; j = 0; k = n-1; while(!(v[j] <= x[a] && x[a] < v[j+1])) { if (x[a] < v[j]) { k = j; } else { i = j+1; } j = div((k-i), 2).quot + i; } if (pow(x[a] - v[j+1],2) < pow(x[a] - v[j],2)) { adj = 1; } else { adj = 0; } y[a] = v[j + adj]; } return y; }') library(microbenchmark) v <- 1:10000 k <- 6.5 microbenchmark(c(max(which(v<k)),min(which(v>k)))) #> Unit: microseconds #> expr min lq mean #> c(max(which(v < k)), min(which(v > k))) 200.907 202.6625 290.4425 #> median uq max neval #> 203.8475 234.6495 1789.479 100 microbenchmark(Position(function(x) k < sort(x), v) - 1) #> Unit: microseconds #> expr min lq mean #> Position(function(x) k < sort(x), v) - 1 262.773 282.9995 296.9819 #> median uq max neval #> 298.919 305.849 428.715 100 microbenchmark(findInterval(k, v)) #> Unit: microseconds #> expr min lq mean median uq max neval #> findInterval(k, v) 33.199 33.7105 50.62627 34.264 37.04 1483.216 100 microbenchmark(nearest_neighbor(k, v)) #> Unit: microseconds #> expr min lq mean median uq max #> nearest_neighbor(k, v) 12.567 13.166 29.45889 13.4945 13.787 1574.045 #> neval #> 100 似乎是最快的:

{{1}}

答案 2 :(得分:0)

这样的事可能是:c(max(which(v<k)),min(which(v>k)))