Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract all rows between start signal and end signal?

I have the following df and I would like to extract all rows based on the following start and end signals.

Start signal : When status changes from 1 to 0 End signal : When status changes from 0 to -1.

df <- data.frame(time = rep(1:14), status = c(0,1,1,0,0,0,-1,0,1,0,0,0,-1,0))

   time status
1     1      0
2     2      1
3     3      1
4     4      0
5     5      0
6     6      0
7     7     -1
8     8      0
9     9      1
10   10      0
11   11      0
12   12      0
13   13     -1
14   14      0

Desire:

   time status    
4     4      0
5     5      0
6     6      0
10   10      0
11   11      0
12   12      0
like image 881
amyotun Avatar asked Dec 25 '22 13:12

amyotun


2 Answers

Here's a possible solution using the data.table package. I'm basically first grouping by status == 1 appearances and then checking per group if there was also a status == -1, if so, I'm sub-setting the group from the second incident until the -1 incident minus 1

library(data.table)
setDT(df)[, indx := cumsum(status == 1)]
df[, if(any(status == -1)) .SD[2:(which(status == -1) - 1)], by = indx]
#    indx time status
# 1:    2    4      0
# 2:    2    5      0
# 3:    2    6      0
# 4:    3   10      0
# 5:    3   11      0
# 6:    3   12      0 
like image 168
David Arenburg Avatar answered Dec 29 '22 08:12

David Arenburg


We count start and end markers, then use those values and the cumulative-sum of (start - end) to filter rows. The (cumsum(start)-cumsum(end)>1) is a slight fiddle to avoid the cumulative counts being upset by row 2 which starts but doesn't end; otherwise row 14 would unwantedly get included.

require(dplyr)

df %>% mutate(start=(status==1), end=(status==-1)) %>%
       filter(!start & !end & (cumsum(start)-cumsum(end)>1) ) %>%
       select(-start, -end)

#   time status
# 1    4      0
# 2    5      0
# 3    6      0
# 4   10      0
# 5   11      0
# 6   12      0
like image 35
smci Avatar answered Dec 29 '22 08:12

smci