I have a set of integer intervals in some range, e.g. 1-20, and I would like to generate complementary, contiguous intervals to them, like so:
intervals <- list(3:6, 10:11, 19:20)
complementary_intervals <- list(1:2, 7:9, 12:18)
Alternatively, I’ll have a dataframe/tibble of start and end integers:
library(tidyverse)
intervals <- tribble(
~start, ~end,
3, 6,
10, 11,
19, 20
)
How can I find the complementary intervals? I’ve tried using set_diff to generate the integers not included in the intervals, but then I’m stuck finding contiguous intervals from those.
>Solution :
Following @Maël’s suggestion in the comments, I post my comment as an answer.
Try
# data
intervals <- list(3:6, 10:11, 19:20)
complementary_intervals <- list(1:2, 7:9, 12:18)
# task
x <- setdiff(1L:20L, unlist(intervals))
( y <- split(x, cumsum(c(1L, diff(x) != 1L))) )
which gives
#> $`1`
#> [1] 1 2
#>
#> $`2`
#> [1] 7 8 9
#>
#> $`3`
#> [1] 12 13 14 15 16 17 18
Of course, the two lines could be easily rewritten as piped version. This would hold the environment clean – good idea. To compare the results with base R you could utilise mapply() as follows
mapply(FUN = "%in%", complementary_intervals, y)
Created on 2023-10-11 with reprex v2.0.2