1

I am excepting the below code to do the following: - if the current value is smaller then the previous one, change it with the previous one.

But, as you already guessed, it doesn't behave this way. When I print i between iterations, I can see that the transformations are done, but they are not implemented in the drop_rate list.

Any suggestions how to upgrade this code so changes are made in the list?

drop_rate<-list(
x1=c(0.0000000,0.2666667,0.3466667,0.4666667,0.3866667,0.7333333),
x2=c(0.0000000,0.3076923,0.4102564,0.5000000,0.4230769,0.7307692),
x3=c(0.0000000,0.2763158,0.3815789,0.4736842,0.4210526,0.7368421),
x4=c(0.0000000,0.2987013,0.3896104,0.5064935,0.4285714,0.7402597),
x5=c(0.0000000,0.3116883,0.4025974,0.5064935,0.4285714,0.7272727))

for (i in drop_rate){
  if (i[1]>i[2]){i[2]=i[1]}
  if (i[2]>i[3]){i[3]=i[2]}
  if (i[3]>i[4]){i[4]=i[3]}
  print(i)
  if (i[4]>i[5]){i[5]=i[4]}
  print(i)
  if (i[5]>i[6]){i[6]=i[5]}
}

Expected outpot (what should change is delimited with **):

0.0000000,0.2666667,0.3466667,0.4666667,**0.4666667**,0.7333333
0.0000000,0.3076923,0.4102564,0.5000000,**0.5000000**,0.7307692
0.0000000,0.2763158,0.3815789,0.4736842,**0.4736842**,0.7368421
0.0000000,0.2987013,0.3896104,0.5064935,**0.5064935**,0.7402597
0.0000000,0.3116883,0.4025974,0.5064935,**0.5064935**,0.7272727
7
  • You need [[ instead of [. also if/else works on a single element i.e. of length 1. I guess you may need to check if all elements are greater than ? Commented Apr 30, 2020 at 20:30
  • Put them everywhere, this is what i get: Error in if (i[[1]] > i[[2]]) { : missing value where TRUE/FALSE needed Commented Apr 30, 2020 at 20:33
  • Nevermind, solved the error. But it's still not doing the transformations. Commented Apr 30, 2020 at 20:35
  • Can you check my solution below with pmin and Map. If you had showed the expected output, it would be easier to crosscheck Commented Apr 30, 2020 at 20:38
  • I've added an expected output. Hope it's more clear now. You're solution works but not in the way I wanted to. Just adding [[ makes no changes. Commented Apr 30, 2020 at 20:52

1 Answer 1

1

Issue is that [ extraction is still a list with length one. So, we need to do [[. Also, if/else is not vectorized. Based on the updated OP's post, we need to check within each list elements. Here, if we stick with if/else, then a nested for loop is needed

for(i in seq_along(drop_rate)){
     tmp <- drop_rate[[i]]
     for(j  in 2:length(tmp)) {
          if(tmp[j-1] > tmp[j]) {
              tmp[j] <- tmp[j-1]
          }
         }
        drop_rate[[i]] <- tmp 


       }

We can use cummax

drop_rate <- lapply(drop_rate, cummax)
drop_rate
#$x1
#[1] 0.0000000 0.2666667 0.3466667 0.4666667 0.4666667 0.7333333

#$x2
#[1] 0.0000000 0.3076923 0.4102564 0.5000000 0.5000000 0.7307692

#$x3
#[1] 0.0000000 0.2763158 0.3815789 0.4736842 0.4736842 0.7368421

#$x4
#[1] 0.0000000 0.2987013 0.3896104 0.5064935 0.5064935 0.7402597

#$x5
#[1] 0.0000000 0.3116883 0.4025974 0.5064935 0.5064935 0.7272727
Sign up to request clarification or add additional context in comments.

1 Comment

Works like a charm. And a lot more simpler. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.