1
$\begingroup$

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.

$\endgroup$
2
$\begingroup$

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}}

$\endgroup$
  • $\begingroup$ Nice! I didn't know of this new function! Do you know how does it compare with Nearest in terms of efficiency? $\endgroup$ – Fraccalo Jun 29 '18 at 8:23
  • 1
    $\begingroup$ @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. $\endgroup$ – kglr Jun 29 '18 at 8:54
  • $\begingroup$ 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? $\endgroup$ – Luigi Jun 29 '18 at 9:23
  • $\begingroup$ @Luigi, NearestTo is new in v11.3. I would go with Fraccalo's answer for finding nearest and farthest elements. $\endgroup$ – kglr Jun 29 '18 at 9:31
  • $\begingroup$ @kglr Thanks for the benchmark! And yes, the discrepancy in the speed depending on the list length is quite weird $\endgroup$ – Fraccalo Jun 29 '18 at 10:12
2
$\begingroup$

What about:

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
$\endgroup$
  • 1
    $\begingroup$ 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. $\endgroup$ – Luigi Jun 28 '18 at 20:40
  • $\begingroup$ Check the last edit :D $\endgroup$ – Fraccalo Jun 28 '18 at 20:43
  • $\begingroup$ Now, how to select the element that is furthest away from xBest. In other words, what is the opposite of Nearest? thanks! $\endgroup$ – Luigi Jun 29 '18 at 6:43
  • $\begingroup$ See new edit to my answer $\endgroup$ – Fraccalo Jun 29 '18 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.