2
$\begingroup$

I have a Which condition inside a loop such as:

Which[b[i]>74,1,b[i] == "value lower but immediately closest to 74", num = b[i];2,b[i] < num,3] where b[i] is a a number at each iteration starting from 80 and going to 60 at different steps.

I am interested in finding the "value lower but immediately closest to 74" so that I can input it to the conditional. How can I write the line of code such as depending on the step I use for b[i] I always find the "value lower but immediately closest to 74" so that the line b[i] == "value lower but immediately closest to 74" makes sense?

Here's a working example: lets say I have the following values of b[i] for each iteration:

b[1]=80,b[2]=79.999.....b[20]=74.0063,b[21]=73.9884,b[22]=73.9705....etc. Then the condition would be Which[b[i]>74,1,b[i] == 73.9884, num = b[i];2,b[i] < num,3] and num would also be 73.9884. The problem is in the fact that depending on a given step I used I do not know what would be the ""value lower but immediately closest to 74"" to put it in the conditional. Is there any way to do this?. Another way to say the same is to put in this line b[i] == "value lower but immediately closest to 74" the value of b[i] that inmmediately follows after there are no more values higher than 74.

EDIT: I tried writing the part of the which condition that I am interested in as Which[...Round[b[i], 0.1] == 74, num = b[i];2.....]. The problem with that is that for the working example I provided, it num would be 73.9884 and also 73.9705 rather than only the first value of 73.9884. There is also other smaller steps where num would be even more values.

Thank you in advanced,

$\endgroup$
  • 1
    $\begingroup$ Can you please condense your question & provide a MWE? $\endgroup$ – CA Trevillian May 16 at 2:47
  • $\begingroup$ @CATrevillian I modified it to try to make it more clear with a given example. I hope it helps. If you have any questions let me know! Thanks $\endgroup$ – John May 16 at 2:55
  • $\begingroup$ John, thank you. Can you also post a basic set of data which you might use this on? I have a solution in mind, and I see you have posted some data, but a sample set would make it easier for others like myself to answer your question :) final clarification, will this data always be ordered in some way, descending or ascending, etc? $\endgroup$ – CA Trevillian May 16 at 3:18
  • $\begingroup$ @CATrevillian Thank you for trying to help me. Here's another data besides the provided: b[1]=80,...b[20]=74.0007,b[21]=73.9884,b[22]=74.0005,b[23]=74.0002.b[24]=74.000,b[25]=73.9998,b[26]=73.9996,b[27]=73.9995....etc. It always go from high (80) to low (60) at a given step (say 0.001). $\endgroup$ – John May 16 at 3:21
  • $\begingroup$ So when the data is above some number, here it is 74, you’ll output the first value, then when it goes below that number, you’ll hold that number in memory, output the second value, then all others below the memorized number will output the third value? $\endgroup$ – CA Trevillian May 16 at 3:25
2
$\begingroup$

There is assuredly a more efficient way to do this, but this uses the paradigm of Which that you dictated in your question.

data=Range[80,60,-.0001];
num=SelectFirst[data,74>#&];
data[[#]]&@@FirstPosition[data,num]==num
newdata=Table[Which[data[[i]]>=74,1,data[[i]]==num,2,data[[i]]<num,3],{i,1,Length@data,1}];
newdata[[#-1;;#+1]]&@@FirstPosition[data,num]

(* True *)
(* {1, 2, 3} *)

The trick here lies in selecting the num appropriately. This would change, for example, if your data were not explicitly ordered.

SelectFirst[data,74>#&]

(* 73.9999 *)

Using With might allow you to streamline this more:

ClearAll[data, num, newdata];
data = Range[80, 60, -.0001];
With[{num = SelectFirst[data, 74 > # &]},

 newdata = 
  Table[Which[data[[i]] >= 74, 1, data[[i]] == num, 2, 
    data[[i]] < num, 3], {i, 1, Length@data, 1}];
 ]

newdata[[# - 1 ;; # + 1]] & @@ FirstPosition[data, num]

(* {1, 2, 3} *)

Again, this is assuming that your data is ordered such that it is descending.

| improve this answer | |
$\endgroup$
  • $\begingroup$ CA Trevillian thank you for helping. The problem with the solution as it is is that it assumes that I have a list from 80 to 60 in a given steps. What I have is a number (e.g. b[i]) which is updated in each iteration starting from 80 and going to 60. So, in a way I cannot simply select the first number that is lower than 74 a priori because I do not have a list but I number. Unfortunately, I do not know the list before hand so to speak. $\endgroup$ – John May 16 at 4:10
  • 1
    $\begingroup$ I don't follow, why not make a list of the values? If you have the number that is updated in each iteration, why not run through all of the iterations making a list, then apply a solution like this? You can use Select or If or similar test to grab the value once you reach it, and again, if it is ordered, then you could potentially have a check before the setting of the value that changes once the value is set. $\endgroup$ – CA Trevillian May 16 at 4:17
  • 1
    $\begingroup$ Actually, I think you are right. I should be able to make a list of the values during the loop and then use your code!! I think it works that way. I appreciate your help. I will mark it as solve! Thanks ! $\endgroup$ – John May 16 at 4:18

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.