Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Flag in R

Tags:

r

I'm trying to create a variable that holds a value and that is reset when it reaches another predefined values.

For instance. I have some data stored in a vector. In another vector (Result) I want to set the value to -1 when the value in x <= -.50 until x > 0. Same thing if x is >= .50 set value to 1 until x < 0.

x <- c(-.28 , -.32, -.38, -.49, -.52, -.44, -.33, -.28, -.16, 0, .18, .22, .33, .42, .52, .32, .26, 0, -.10, -.15)

Result <- c(0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0 , 1, 1, 1, 0, 0 ,0)

Comb <- data.frame(x, Result)

I can evaluate these conditions individually but I can't figure out how to set a conditional flag that's reset-able.

Thanks

Mike

like image 739
Michael Henning Avatar asked May 11 '26 11:05

Michael Henning


2 Answers

x      <- c(-.28 , -.32, -.38, -.49, -.52, -.44, -.33, -.28, -.16, 0, .18, .22, .33, .42, .52, .32, .26, 0, -.10, -.15)
Result <- c(0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0 , 1, 1, 1, 0, 0 ,0)
Comb   <- data.frame(x, Result)

for(i in 1:nrow(Comb)){
  if(Comb$x[i] <= -.5){
    Comb$Result[i:nrow(Comb)] <- -1
  } 
  if(Comb$x[i] >= .5){
    Comb$Result[i:nrow(Comb)] <- 1
  }
  if(i > 1){
    if(Comb$Result[i-1] == 1 & Comb$x[i] < 0 & Comb$x[i] > -.5){
      Comb$Result[i:nrow(Comb)] <- 0
    }
  }
  if(i > 1){
    if(Comb$Result[i-1] == -1 & Comb$x[i] > 0 & Comb$x[i] < .5){
      Comb$Result[i:nrow(Comb)] <- 0
    }
  }
  if(Comb$x[i]==0){
    Comb$Result[i] <- 0 # Based on the example data, not the narrative
  }
  if(i > 1){
    if(Comb$Result[i-1] == 0 & Comb$x[i] < .5 & Comb$x[i] > -.5){
      Comb$Result[i] <- 0
    }
  }
}

identical(Comb$Result, Result)

TRUE

like image 170
Hack-R Avatar answered May 13 '26 03:05

Hack-R


Here is a vectorized approach using na.locf from zoo package. Since the result only changes values at positions where the absolute value is larger than 0.5 or the value is switching sign, we can find out these positions, fill with corresponding values and fill forward using the na.locf function supposing we are starting from a vector of NAs:

library(magrittr); library(zoo)

# start from a vector of NA of the same length of the vector
rep(NA, length(x)) %>% 
    # place 0 at positions wherever there is a sign change
    replace(c(T, diff(sign(x)) != 0), 0) %>%   
    # place +1 or -1 at positions wherever the absolute value is larger than 0.5
    replace(abs(x) >= 0.5, sign(x[abs(x) >= 0.5])) %>% 
    # fill the NA with the previous values -1, 0 or 1
    na.locf()

# [1]  0  0  0  0 -1 -1 -1 -1 -1  0  0  0  0  0  1  1  1  0  0  0
like image 21
Psidom Avatar answered May 13 '26 03:05

Psidom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!