I would like find the fastes way in R to indentify indexes of elements in Ytimes array which are closest to given Xtimes values.
So far I have been using a simple for-loop, but there must be a better way to do it:
Xtimes <- c(1,5,8,10,15,19,23,34,45,51,55,57,78,120)
Ytimes <- seq(0,120,length.out = 1000)
YmatchIndex = array(0,length(Xtimes))
for (i in 1:length(Xtimes)) {
YmatchIndex[i] = which.min(abs(Ytimes - Xtimes[i]))
}
print(Ytimes[YmatchIndex])
R
is vectorized, so skip thefor
loop. This saves time in scripting and computation. Simply replace thefor
loop with anapply
function. Since we're returning a 1D vector, we usesapply
.YmatchIndex <- sapply(Xtimes, function(x){which.min(abs(Ytimes - x))})
Proof that
apply
is faster:See
?apply for more
.We can use
findInterval
to do this efficiently. (cut
will also work, with a little more work).First, let's offset the
Ytimes
offsets so that we can find the nearest and not the next-lesser. I'll demonstrate on fake data first:The second column (prepended with a
-Inf
will give us the breaks. Notice that each is half-way between the corresponding value and its follower.Okay, let's apply this to your vectors:
(I'm using
cbind
just for side-by-side demonstration, not that it's necessary.)Benchmark:
Obligatory Rcpp solution. Takes advantage of the fact that your vectors are sorted and don't contain duplicates to turn an
O(n^2)
into anO(n)
. May or may not be practical for your application ;)C++:
R: