Assign a value to a line if it matches the line and the previous line

These are my events and the X and Y coordinates of each event. I want to assign the value “1” to the event if this event = 0 <x <4 and 0 <y <4 And the previous event = x> 4 and y> 4 and assign the value “0” if the criteria are not met. Here is my starting table:

Event    LocX    LocY
  1       6        6
  2       3        2
  3       3        7
  4       1        4
  5       7        4
  6       1        2
  7       8        5
  8       1        1

My final table will look like this:

Event    LocX    LocY   Value 
  1       6        6      0
  2       3        2      1
  3       3        7      0
  4       1        4      0
  5       7        4      0
  6       1        2      1
  7       8        5      0
  8       1        1      1

Any help would be appreciated!

+4
source share
6 answers

Another approach data.table. This is similar to translating the neilfws dplyr approach when using a function shiftto compare values ​​with the previous one.

library(data.table)
setDT(dt)[ ,Value := ifelse(LocX < 4 & 
                            LocY < 4 &
                            shift(LocX, type = "lag") > 4 &
                            shift(LocY, type = "lag") > 4,
                            1, 0)]
dt
   Event LocX LocY Value
1:     1    6    6     0
2:     2    3    2     1
3:     3    3    7     0
4:     4    1    4     0
5:     5    7    4     0
6:     6    1    2     0
7:     7    8    5     0
8:     8    1    1     1

Data

dt <- read.table(text = "Event    LocX    LocY
  1       6        6
                 2       3        2
                 3       3        7
                 4       1        4
                 5       7        4
                 6       1        2
                 7       8        5
                 8       1        1",
                 header = TRUE)
+1
source

A dplyr ifelse. df1.

library(dplyr)
df1 %>% 
  mutate(Value = ifelse(LocX > 0 & 
                        LocX < 4 & 
                        LocY > 0 & 
                        LocY < 4 & 
                        lag(LocX) > 4 & 
                        lag(LocY) > 4, 1, 0))

  Event LocX LocY Value
1     1    6    6     0
2     2    3    2     1
3     3    3    7     0
4     4    1    4     0
5     5    7    4     0
6     6    1    2     0
7     7    8    5     0
8     8    1    1     1
+3

, .

n <- nrow(dat)
log1 <- 0 < dat$LocX & dat$LocX < 4 & 0 < dat$LocY & dat$LocY < 4
log2 <- c(FALSE, c(dat$LocX[-n] > 4 & dat$LocY[-n] > 4))
dat$Value <- as.integer(log1 & log2)
dat
#  Event LocX LocY Value
#1     1    6    6     0
#2     2    3    2     1
#3     3    3    7     0
#4     4    1    4     0
#5     5    7    4     0
#6     6    1    2     0
#7     7    8    5     0
#8     8    1    1     1

:

dat <-
structure(list(Event = 1:8, LocX = c(6L, 3L, 3L, 1L, 7L, 1L, 
8L, 1L), LocY = c(6L, 2L, 7L, 4L, 4L, 2L, 5L, 1L)), .Names = c("Event", 
"LocX", "LocY"), class = "data.frame", row.names = c(NA, -8L))
+1
source

Here is one way:

#Data table version:
df$Value <- 0
df[intersect(which(LocX>4&LocY>4)+1,which(LocX>0&LocX<4&LocY>0&LocY<4)),"Value"]<-1

#Data frame version:
df$Value <- 0
df[with(df,intersect(which(LocX>4&LocY>4)+1,which(LocX>0&LocX<4&LocY>0&LocY<4))),]<-1

Conclusion:

   Event LocX LocY Value
1:     1    6    6     0
2:     2    3    2     1
3:     3    3    7     0
4:     4    1    4     0
5:     5    7    4     0
6:     6    1    2     0
7:     7    8    5     0
8:     8    1    1     1

Sample data:

require(data.table)

df <- fread("Event   LocX     LocY
             1       6        6
             2       3        2
             3       3        7
             4       1        4
             5       7        4
             6       1        2
             7       8        5
             8       1        1")
+1
source

Just to show that combining an entire group of logical states in the R base is also not a big problem. Just create a list and then combine them recursively with the statement &(s) using Reduce. This is very similar to what it dplyr case_whendoes internally:

Reduce(`&`, with(dat, 
  list(
    LocX > 0, 
    LocX < 4, 
    LocY > 0, 
    LocY < 4, 
    c(FALSE, head(LocX,-1) > 4), 
    c(FALSE, head(LocY,-1) > 4) 
  )
))
#[1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
+1
source

I have this loop forthat will give the desired result.

for(i in 1:nrow(df)){
  df$Value[i] = 0
  if(i > 1){
    if(df$LocX[i] < 4 & df$LocY[i] < 4 & df$LocX[i-1] > 4 & df$LocY[i-1] > 4){
      df$Value[i] = 1
    }
  }
}
0
source

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


All Articles