Filter consecutive identical values if at start or end of unique id

Viewed 46

I have a dataset with GPS locations of birds doing multiple trips from a colony. I want to remove all points within 3 km from the colony, but ONLY those that are at the beginning or the end of an individual trip (Unique_id). If they come to within 3 km of the colony in the middle of a trip, and then head off again without returning to the colony first, I want to retain these points.

I calculated the distance to the colony and then defined using a logical column whether the location was < 3km (1) or > 3km (0). With the coordinates removed, the dataframe looks a bit like the below dummy data. So from here, I am looking to define something along the lines of "remove rows with dist3k == 1 for the first or last consecutive "1"s of a Unique_id.

Hope this makes sense, and look forward to suggestions.

# what the data looks like 
data_orig <- data.frame(
  Index = rep(c('1','2','3','4','5','6','7','8','9','10',
                '11','12','13','14','15','16','17','18','19','20')),
  Unique_id = rep(c('A1','A2'), each = 10),
  dist3k = rep(c('1','1','0','0','0','1','1','0','0','1','1','1','1','0','1','0','1','0','1','1')))

# what I want the output to be 
data_new <-data_orig[-c(1,2,10,11,12,13,19,20),]

1 Answers

Here's an approach with dplyr and cumsum.

It works by inverting the binary values dist3k!=1 and then calculating the cumulative sum cumsum(dist3k!=1), which is always zero in the beginning when the vector starts with 1.

Then for the last values the same is done but in reverse.

We now have two vectors fil1 and fil2 where we can filter looking for non-zero values.

library(dplyr)

data_orig %>% 
  group_by(Unique_id) %>% 
  mutate(fil1=cumsum(dist3k!=1), fil2=rev(cumsum(rev(dist3k)!=1))) %>% 
  filter(fil1!=0 & fil2!=0) %>% 
  ungroup() %>% 
  select(-starts_with("fil"))
# A tibble: 12 × 3
   Index Unique_id dist3k
   <chr> <chr>     <chr> 
 1 3     A1        0     
 2 4     A1        0     
 3 5     A1        0     
 4 6     A1        1     
 5 7     A1        1     
 6 8     A1        0     
 7 9     A1        0     
 8 14    A2        0     
 9 15    A2        1     
10 16    A2        0     
11 17    A2        1     
12 18    A2        0
Related