Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the closest element in a vector for every element in another vector without duplicates?

Tags:

r

vector

I got this code which create two vectors and for each element from a I want to get the closest element in b :

a = rnorm(100)
b = rnorm(100)
c = vapply(a, function(x) which.min(abs(b - x)), 1)
table(duplicated(c))

FALSE  TRUE 
   61    39 

As you can see this method is prompt to give a lot of duplicates which is normal but I would like to not have duplicates. I thought of deleting occurence from b once an index has been selected but I don't know how to do it under vapply.

like image 857
Wicelo Avatar asked Sep 24 '14 10:09

Wicelo


People also ask

How do you find the closest element to a selector?

The closest () method searches up the DOM tree for the closest element which matches a specified CSS selector. It starts at the element itself, then tests the parent, grandparent, and so on until a match is found. If a match is not found, this method returns null .

How to find the closest greater element of an array?

We pick an outer element one by one. For every picked element, we traverse remaining array and find closest greater element. Time complexity of this solution is O (n*n)

Is it possible to get the position of the closest vector?

Yes, though you could hand it all points at once as well. Per default query returns the closest vector in A to the given one. And it returns the distance to that vector and the position of the closest vector in A.

How to compute the closest value in a vector using MATLAB?

To compute the closest value in a vector “N” for each element of “V”, try the following code with example vectors “N” and “V”: Note that if there is a tie for the minimum value in each column, MATLAB chooses the first element in the column.


2 Answers

The closest match you are going to get is by sorting the vectors and then pairing them off. The following permuation on b should allow you to do that.

p <- order(b)[order(order(a))] # order on b and then back transform the ordering of a

sum(abs(a-b[p]))
[1] 20.76788

Clearly, allowing duplicates does make things much closer:

sum(abs(a-b[c]))
[1] 2.45583
like image 62
James Avatar answered Nov 15 '22 08:11

James


This is very bad programming, but may work and is vectorized...

   a <- rnorm(100)
   b <- rnorm(100)
   #make a copy of b (you'll see why)
   b1<-b
   res<- vapply(a, function(x) {ret<-which.min(abs(b1 - x));b1[ret]<<-NA;return(ret)}, 1)
like image 42
nicola Avatar answered Nov 15 '22 08:11

nicola