Home > Back-end >  Iterate until every row of column satisfies condition
Iterate until every row of column satisfies condition

Time:08-09

I need to adjust one variable until it satisfies the condition that none of its rows are higher than one specific value. Here is some context:

  1. I have 2 vectors: 'a' and 'b'

  2. I normalize a and b to calculate their ratio 'c' (a_norm/b_norm)

  3. Every row of 'c' must not be higher than a constant 'd'. Any 'c' row that is higher than d should be transformed into d.

  4. After all 'c' rows that need to are adjusted (let's call this new column c_adjusted), I must recalculate a_norm (c_adjusted*b) (note that this will not make a_norm to be normalise, so let's call it a_adjusted)

  5. I normalize a_adjusted to estimate the new a_norm (a_adjusted_norm = a_adjusted/sum(a_adjusted)*100

  6. I calculate again c to check if all rows satisfy the condition after the adjustment. If any is still higher than d, I have to repeat the process until the condition is satisfied. At the end I would like the final a_adjusted_norm as the final result.

Does anybody knows how to achieve this? Here is a reproducible example:

set.seed(8)

#create dataframe

a<- runif(100, min = 0, max = 10)
b<- runif(100, min = 0, max = 10)
a_norm <- a/sum(a)*100
b_norm <- b/sum(b)*100

c <- a_norm / b_norm
c_cap <- 1 #C must not be higher than c_Cap

df <- data.frame(a_norm, b_norm, c)

df <- df %>%
  mutate(c_adjusted = ifelse(c >= c_cap, c_cap, c), #We adjust c rows that are higher than c_cap
         a_adjusted = c_adjusted*b_norm, #We calculate the adjusted a with adjusted c
         a_adjusted_norm = a_adjusted/sum(a_adjusted)*100) #Normalize adjusted a

#We calculate again c to see if it matches condition
df <- df %>%
  mutate(c = a_adjusted_norm/b_norm) #see if c satisfy condition after adjusting variables

#If any row of C is still higher than cap, I must adjust it again and repeat the process until all rows match the condition

Thanks in advance!

CodePudding user response:

Generally you can do:

a <- runif(10, min = 0, max = 10)
b <- runif(10, min = 0, max = 10)

a_norm <- a/sum(a)*100
b_norm <- b/sum(b)*100

cap <- 1

c <- a_norm / b_norm

while (max(c) > cap) {
  c[c>cap] <- cap

  a_adjusted <- c * b_norm
  a_adjusted_norm <- a_adjusted/sum(a_adjusted)*100

  c <- a_adjusted_norm/b_norm
}

However, this seems to never work, because while your approach shrinks the higher values towards 1, it at the same time pushes smaller values than 1 to become larger than 1. Which means that the loop will never end (at least I stopped it manually after some time)

So you probably need to adjust the formula to recalculate your c values!

  • Related