最も近い値を持つ要素のインデックスを返す

掲題の件、あると思います。

例えばこういうやつ(z(=3)の値に最も近いxの要素(=2.9)を探す)。

> z <- 3
> x <- c(1,2,2.9,3.5,4)
> index <- which.min(abs(z - x))
> x[index]
[1] 2.9

これをzがベクトルのときでも動くようにしたいと考えた2実装が以下。

1つ目は単純に sapply を使っていて、2つ目は findInterval区間を見つけつつちょいと補正(単純にやると最も近い値にならないときがある)をしたもの。

1億個要素を持つベクトル(x)と、複数個値を持ってる適当なベクトル(y)を使って2つのやり方の時間を測ると

> x <- sort(runif(10^8, min=1, max=4))
> ys <- seq(2,3.9,by=0.3)
> system.time({ ce_1 <- sapply(ys, function(z)which.min(abs(z - x))) })
   ユーザ   システム       経過  
     2.592      1.650      4.362 
> system.time({ ce_2 <- findInterval(ys, 0.5*(x[-length(x)] + x[-1])) + 1 })
   ユーザ   システム       経過  
     1.285      0.544      1.830 

findInterval で書いたほうが早いんで良さそう。

念の為結果をチェックすると

> all(ce_1 == ce_2)
[1] TRUE

ちゃんとあってる。

まぁ、パッケージにするまでもないし、自分で関数として持っておくか〜という決断をする。