1
$\begingroup$

I have a list as data which is uploaded here, due to its long length. We can consider to the list as a collection of {x,y} pairs.

Please consider a value for example 3.63, above this value we first arrive 4.814 (we called it y2), and below this value we first arrive 3.08 (we called it y1). As far as we can see, they (3.08 and 4.814) are y with any x.

I want to access {y1,y2,y2-y1} that are the nearer ys to a special value which is 3.63 here. For example I found here the triple collection is {3.08, 4.814, 1.734}.

In a plot we can show the aim as the below plot in which y1 and y2 are highlighted.

enter image description here

$\endgroup$
  • $\begingroup$ Please make your question more precise (e.g., by using correct grammar to phrase it). I don't get what you are looking for. What is y1 and y2? $\endgroup$ – Henrik Schumacher Jan 12 '18 at 16:06
  • $\begingroup$ y1 and y2 are the y's of two pairs {x1,y1} and {x2,y2}, (just their y's are important which must very close to the value 3.63) $\endgroup$ – Inzo Babaria Jan 12 '18 at 16:12
  • $\begingroup$ you need a precise definition of what you mean by "nearer" $\endgroup$ – george2079 Jan 12 '18 at 16:12
  • $\begingroup$ What does "close" mean here? Please give additional information in the post, not in the comments. $\endgroup$ – Henrik Schumacher Jan 12 '18 at 16:13
  • $\begingroup$ why would you use Get Coordinates when you have the actual input data available? $\endgroup$ – george2079 Jan 12 '18 at 16:18
6
$\begingroup$

Those two y-values that are nearest to 3.63 are extracted below along with their difference:

data = Import["rereimport.dat"];
{#, #2, #2 - #} & @@ Nearest[data[[All, 2]], 3.63, 2]
{3.08, 3.055, -0.025}'

The following gives instead one y-value above 3.63, and one below 3.63:

With[{ys = Union[data[[All, 2]]]}, {#, #2, #2 - #} & @@
   Nearest[ys, First[Nearest[MovingAverage[ys, 2], 3.63, 1]], 2]]
{3.08, 4.831, 1.751}
$\endgroup$
  • $\begingroup$ Your answer seems to have a bug. For example: SeedRandom[5]; data = RandomReal[10, {10, 2}]; near = RandomReal[10]; With[{ys = Union[data[[All, 2]]]}, Nearest[ys, Nearest[MovingAverage[ys, 2], near, 1][[1]], 2]] produces a bracket that doesn't include the target. $\endgroup$ – Carl Woll Jan 25 '18 at 3:56
3
$\begingroup$

You could use Nearest. The following answer is similar to my LeftNeighbor function from Given an ordered set S, find the points in S corresponding to another list:

Bracket[data_] := Module[{ord = Ordering[data], s},
    s = data[[ord]];
    BracketFunction[s, ord, Nearest[s->"Index"]]
];
Bracket[data_, list_] := Bracket[data][list]

BracketFunction[s_, o_, nf_][list_] := With[{n = nf[list][[1]]},
    With[{lindex=n - UnitStep[s[[n]] - list]},
        o[[{lindex, lindex+1}]]
    ]
]

BracketFunction[s_, o_, nf_][list_List] := With[{n = nf[list][[All, 1]]},
    With[{lindex=n - UnitStep[s[[n]] - list]},
        Transpose@{o[[lindex]], o[[lindex+1]]}
    ]
]

BracketFunction returns the indices of the data that bracket the input. For example:

bf = Bracket[data[[All, 2]]];
indices = bf[3.63]
data[[indices, 2]]

{391, 402}

{3.08, 4.831}

where I only return the y values here. BracketFunction also works with lists of data:

indices = bf[{2.2, 3.63}]
data[[#]]& /@ indices

{{396, 395}, {391, 402}}

{{{2.2845, 1.969}, {2.3422, 2.255}}, {{2.5731, 3.08}, {2.5731, 4.831}}}

where I return the {x, y} values this time.

If desired, one could add a SummaryBox format to BracketFunction.

$\endgroup$
2
$\begingroup$

here is a simple way to get the nearest point above and below.

data = RandomReal[{0, 10}, 100];
SortBy[data, 1/(# - 3.08) &][[{1, -1}]]

{3.03482, 3.13265}

caveat, this throws an error if any data point exactly equals the special value.

$\endgroup$

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.