Find the first previous value other than condition

I have a dataframe with position in pos1 and sampling time in ts. In addition, I have a threshold / hysteresis that is on both sides (positive and negative).

  n t.s.       pos1     pos2     pos3  X   side
  1   0  0.0000000 0.000000 0.000000 NA MIDDLE
  2  78 -0.4541016 1.430664 1.430664 NA MIDDLE
  3 109 -0.4199219 1.430664 1.430664 NA MIDDLE
  4 147 -0.4150391 1.430664 1.430664 NA MIDDLE
  5 197 -0.4345703 1.430664 1.425781 NA MIDDLE
  6 247 -0.4541016 1.430664 1.430664 NA MIDDLE

In this case, hysteresis = 0.5 / -0.5. There is a light that turns on as soon as pos1> Hysteresis, and it will not turn until pos1 <-0.5. To do this, I created an added variable in my framework (side) that tells me that pos1 is above 0.5 (ON), between 0.5 and -0.5 (in the middle) or below -0.5 (OFF )

I would like to make a variable (let it be light) that has only two possibilities ON / OFF. To do this, I need to assign from average to one of two, and this depends on the last different side factor (ON / OFF).

I am having trouble finding a function that found previous variables after the middle condition was met.

+4
source share
2 answers

Here is what I can offer at the moment. Given the sequence of values pos1, the light state switches from ON to OFF in the case of a value pos1 < -0.5and from OFF to ON in the case of a value pos1 > 0.5.

The light state (ON / OFF) is encoded in a variable statewith a value 1for ON and 0OFF:

set.seed(1234)
n_length <- 100 # As an example we look at 100 consecutive states / signals
pos1 <- rnorm(n_length) # normally distributed sequence of signals with mean=0 
switch_on <- (pos1 > 0.5) # potential signals to turn on the light
switch_off <- (pos1 < -0.5) # potential switch-off signals
state <- vector(length=n_length) 
check_switch <- function(state, switch_off, switch_on){
  if(state == 1 && switch_off) state <- 0
  if(state == 0 && switch_on) state <- 1
  return(state)
}
state[1] <- 1 # the default initial state is chosen as "ON". 
state[1] <- check_switch(state[1],switch_off[1],switch_on[1])
for (i in 2:n_length){
  state[i] <- state[i-1]
  state[i] <- check_switch(state[i], switch_off[i], switch_on[i])
}
#> head(cbind(pos1,state),10)
#            pos1 state
# [1,] -1.2070657     0
# [2,]  0.2774292     0
# [3,]  1.0844412     1
# [4,] -2.3456977     0
# [5,]  0.4291247     0
# [6,]  0.5060559     1
# [7,] -0.5747400     0
# [8,] -0.5466319     0
# [9,] -0.5644520     0
#[10,] -0.8900378     0

Unfortunately, this is not a type of popular single-line vectorized solution. I'm not sure if it can be translated into a much shorter form, but maybe someone will find a more compact answer. In any case, I hope that the code is useful and that it gives the correct result.

+1

, , RHertel ( ). , .

data$side<-vector("character", length = lengthExp)
for(i in 1:lengthExp){
  if (data$pos1[i]>=Hysteresis)
    data$side[i]<- "ON"
  if (data$pos1[i]>= -Hysteresis && data$pos1[i]<= Hysteresis)
    data$side[i]<- "MIDDLE"
  if (data$pos1[i]<= -Hysteresis)
    data$side[i]<- "OFF"
}

data$light<-vector("character", length = lengthExp)
for(i in 1:lengthExp){
  if(i==1 && data$side[i]=="MIDDLE") data$light <- "OFF"
  if(i>1){
    if (data$side[i]== "ON")
      data$light[i]<- "ON"
    if (data$side[i]== "MIDDLE") 
      data$light[i]<- data$light[i-1]
    if (data$side[i]== "OFF")
      data$light[i]<- "OFF"
  }
}
+2

Source: https://habr.com/ru/post/1598889/


All Articles