Reputation: 217
a
and b
are two vectors of real numbers.
They do not necessarily have the same length.
The distance between the i
th element of a
and the j
th element of b
is defined as abs(a[i] - b[j])
How would you compute the smallest distance between any element of a
and any element of b
without explicit loops?
Here is what I did: min(sapply(X=1:length(b), FUN=function(x) abs(a - b[x])))
.
However, I have the feeling there is something better to do...
Upvotes: 3
Views: 6150
Reputation: 60924
I'd use the dist
function to create a distance matrix, and then find the minimum distance in that. This is probably much faster than an explicit loop in R (including sapply
).
a = runif(23)
b = runif(10)
d_matrix = as.matrix(dist(cbind(a,b)))
d_matrix[d_matrix == 0] <- NA
sqrt(min(d_matrix, na.rm = TRUE))
Note that cbind
recycles the smaller vector. So this function is probably not optimal, but for vectors that do not differ that much in size still much fast than an explicit loop.
And to find which pair of elements had this distance (although the recycling introduces some challenges here):
which(d_matrix == min(d_matrix, na.rm = TRUE), arr.ind = TRUE)
Upvotes: 4
Reputation: 93803
Here's an attempt:
a <- c(9,5,6); b <- c(6,9)
# a
#[1] 9 5 6
# b
#[1] 6 9
combos <- sapply(b,function(x) abs(x-a))
# or an alternative
combos <- abs(outer(a,b,FUN="-"))
You could then get the minimum distance with:
min(combos)
If you wanted to get the respective indexes of the minimum values you could do:
which(combos==min(combos),arr.ind=TRUE)
# each matrix row has the 2 indexes for the minimums
# first column is 'a' index, second is 'b' index
# row col
# [1,] 3 1
# [2,] 1 2
Upvotes: 3