R how to filter a data frame based on conditions in following rows?

Viewed 56

I have a dataframe which looks like the following:

a<-c(1,1,-1,1,-1,1,-1,1,1,1,1)
b<-c(100,200,50,100,78,45,78,34,56,32,45)
c<-c(3,2,4,1,3,2,1,3,5,1,2)
d<-c(3400,3403,3407,3408,3412,3423,3436,3245,3234,3456,2345)
df<-cbind(a,b,c,d)
df
       a   b c    d
 [1,]  1 100 3 3400
 [2,]  1 200 2 3403
 [3,] -1  50 4 3407
 [4,]  1 100 1 3408
 [5,] -1  78 3 3412
 [6,]  1  45 2 3423
 [7,] -1  78 1 3436
 [8,]  1  34 3 3245
 [9,]  1  56 5 3234
[10,]  1  32 1 3456
[11,]  1  45 2 2345

which contains a lot more rows. I want to filter in the following way: If column c = 3, i am looking for following rows, which have the same a and b column values as my c=3 column, the c column value has to be 1 and between that two rows there must be a difference < 10 in column d.

So in the provided sample the output should be:

      a   b c    d
[1,]  1 100 3 3400
[4,]  1 100 1 3408

Since a and b columns have the same values, the c column has a value of 3 followed by 1 and between the d values there is a difference less than 10. For example,


      a   b c    d
[5,] -1  78 3 3412
[7,] -1  78 1 3436

should not be included in the output, since in column d the difference between the values is bigger than 10.

Is there any possibility to implement that? Sorry if that is a stupid question, i am quite new to R.

EDIT: New data frame:

       a   b c    d
 [1,]  1 100 1 3400
 [2,]  1 200 2 3403
 [3,] -1  50 4 3407
 [4,]  1 100 3 3408
 [5,] -1  78 3 3412
 [6,]  1  45 2 3423
 [7,] -1  78 1 3436
 [8,] -1  34 3 3445
 [9,]  1  56 5 3234
[10,] -1  34 1 3454
[11,]  1  45 2 3645

Desired outcome:

 [8,] -1  34 3 3445
[10,] -1  34 1 3454

Only pairs, where the c column of the first row =3 should be considered and not cases where the first row has column c entry = 1 and the second has entry = 3.

1 Answers

We can convert to data.frame and then do a group by filter

library(dplyr)
df %>% 
    filter(c %in% c(3, 1)) %>%
    group_by(a, b) %>% 
    filter(first(c) == 3, any(diff(d) < 10)) %>% 
    ungroup

# A tibble: 2 x 4
#      a     b     c     d
#   <dbl> <dbl> <dbl> <dbl>
#1     1   34     3  3445
#2     1   34     1  3454

data

 df<- data.frame(a,b,c,d)
Related