我有一个酉段[0,1]和几个点,由向量v
表示。此外,我有一个介于0和1之间的数字k
,我想知道该数字落入的区间索引是什么。
我想知道是否存在一种聪明的方式而不是循环元素。
k <- 0.67
v <- c( 0.12 , 0.25 , 0.48 , 0.78 , 1)
答案 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)))