When the dates are sorted, there's no repeated status for trap_ID=2. Is that what you intended?
For the output, is this what you had in mind?
library(lubridate)
library(tidyverse)
df <-
tribble(
~trap_ID, ~date, ~status,
1, "october 01, 2016", "open",
1, "october 03, 2016", "closed",
1, "october 04, 2016", "open",
1, "october 10, 2016", "closed",
1, "october 12, 2016", "closed",
2, "october 12, 2016", "open",
2, "october 03, 2016", "open",
2, "october 10, 2016", "closed") %>%
mutate(
date = mdy(date))
df %>%
mutate(date=as_date(date)) %>%
arrange(trap_ID, date) %>%
group_by(trap_ID) %>%
filter(lag(status) %in% c(NA_character_, "open") & status=="closed" |
lead(status) %in% c(NA_character_, "closed") & status=="open")
#> # A tibble: 7 × 3
#> # Groups: trap_ID [2]
#> trap_ID date status
#> <dbl> <date> <chr>
#> 1 1 2016-10-01 open
#> 2 1 2016-10-03 closed
#> 3 1 2016-10-04 open
#> 4 1 2016-10-10 closed
#> 5 2 2016-10-03 open
#> 6 2 2016-10-10 closed
#> 7 2 2016-10-12 open
Created on 2022-05-16 by the reprex package (v2.0.1)