Subset 'n' rows with minimum distance of 'd'

Viewed 25

I have a data frame that looks like this:

dataframe <- data.frame(condition = c("light", "light", "light", "light", "dark", "light", "light", "light", "dark", "light", "light", "dark", 
                                      "light", "light", "light", "dark", "light", "dark", "light", "light", "light", "light", "dark"))

 condition
1      light
2      light
3      light
4      light
5       dark
6      light
7      light
8      light
9       dark
10     light
11     light
12      dark
13     light
14     light
15     light
16      dark
17     light
18      dark
19     light
20     light
21     light
22     light
23      dark

I want to subset 'light' rows that in between the 'dark' rows, that have 3 or more subsequent rows where condition == 'light'. For example, I want to end up with:

  condition
1      light
2      light
3      light
4      light
5       dark
6      light
7      light
8      light
9       dark
12      dark
13     light
14     light
15     light
16      dark
18      dark
19     light
20     light
21     light
22     light
23      dark

How do I do this? Thanks in advance.

1 Answers

We can use rleid from data.table to create a grouping column, and then filter based on the condition

library(dplyr)
library(data.table)
dataframe %>% 
    group_by(grp = rleid(condition)) %>% 
    filter(n() >=3| condition == 'dark') %>%
    ungroup %>%
    select(-grp)

-output

# A tibble: 20 x 1
   condition
   <chr>    
 1 light    
 2 light    
 3 light    
 4 light    
 5 dark     
 6 light    
 7 light    
 8 light    
 9 dark     
10 dark     
11 light    
12 light    
13 light    
14 dark     
15 dark     
16 light    
17 light    
18 light    
19 light    
20 dark     

Or use rle from base R to create a logical vector for subsetting

subset(dataframe, with(rle(condition),
     rep(lengths >=3|values == 'dark', lengths)))

-output

    condition
1      light
2      light
3      light
4      light
5       dark
6      light
7      light
8      light
9       dark
12      dark
13     light
14     light
15     light
16      dark
18      dark
19     light
20     light
21     light
22     light
23      dark
Related