Select element of list based on proximity to a certain value

I have the following matrix:

data = {{0.795718, 0.737, 0.813, 1.27301}, {0.846782, 0.767, 0.86,1.2859},
{0.742211, 0.691, 0.767, 1.27714}, {0.754719, 0.706, 0.783,1.27319},
{0.743044, 0.691, 0.783, 1.26768}, {0.745167, 0.706,0.783, 1.28189},
{0.815733, 0.752, 0.86,1.25376}, {0.551127, 0.553,0.553, 1.2084}};


each row is made up of a list of 4 elements: {x1,x2,x3,y}. I would like to apply a rule to the matrix that allows me to select, row by row, only one of the first 3 elements, the one that is closest to a certain value, let us say xbest (eg 0.8 in the example with the data above), let us call this element xwin. Eventually, I would like have a new matrix with rows of 2 elements only: {xwin,y}. Your help is appreciated.

This seems like a good case for NearestTo:

NearestTo[x]
is an operator form that yields Nearest[elems, x] when applied to a list elems.

nTo = NearestTo[xbest, 1];
Join[nTo /@ data[[All, ;; 3]], data[[All, {4}]], 2]


{{0.795718, 1.27301}, {0.767, 1.2859}, {0.767, 1.27714}, {0.783, 1.27319}, {0.783, 1.26768}, {0.783, 1.28189}, {0.815733, 1.25376}, {0.553, 1.2084}}

• Nice! I didn't know of this new function! Do you know how does it compare with Nearest in terms of efficiency? Jun 29, 2018 at 8:23
• @Fraccalo, it seems that for long lists they are similar, but shorter lists, to my surprise, Nearest is much faster: dt=RandomInteger[100000,s]; NearestTo[99]@dt// RepeatedTiming versus Nearest[dt, 99]// RepeatedTiming  for s=100 and s = 10^6.
– kglr
Jun 29, 2018 at 8:54
• I am using v10.0 and NearestTo is not defined there. How to circumvent this? and how to get the element (from the first 3) that is the furthest away from xBest? Jun 29, 2018 at 9:23
• @Luigi, NearestTo is new in v11.3. I would go with Fraccalo's answer for finding nearest and farthest elements.
– kglr
Jun 29, 2018 at 9:31
• @kglr Thanks for the benchmark! And yes, the discrepancy in the speed depending on the list length is quite weird Jun 29, 2018 at 10:12

xBest = 0.8;
{First@Nearest[#[[1 ;; 3]], xBest], #[[4]]} & /@ data


And for the "Farthest" function:

xBest = 0.8;
{First@Nearest[#[[1 ;; 3]], xBest,
DistanceFunction -> (-Abs[#1 - #2] &)], #[[4]]} & /@ data

• could work! however, if you apply it to data, you see that the last row has duplicated value (3 elements rather than 2). With xBest=0.8058 you get {{0.813, 1.27301}, {0.767, 1.2859}, {0.767, 1.27714}, {0.783, 1.27319}, {0.783, 1.26768}, {0.783, 1.28189}, {0.815733, 1.25376}, {0.553, 0.553, 1.2084}} as result. Jun 28, 2018 at 20:40
• Check the last edit :D Jun 28, 2018 at 20:43
• Now, how to select the element that is furthest away from xBest. In other words, what is the opposite of Nearest? thanks! Jun 29, 2018 at 6:43
• See new edit to my answer Jun 29, 2018 at 8:06