tidyverse / lubridate

Make working with dates in R just that little bit easier
https://lubridate.tidyverse.org
GNU General Public License v3.0
728 stars 207 forks source link

interval A overlap interval B #1106

Closed yinshiyi closed 1 year ago

yinshiyi commented 1 year ago

Goal to output that part of none overlap. Screen Shot 2023-01-05 at 11 31 44 PM AKA, the part of A that is not overlapping with B.

setdiff(a,b) a 2023-01-09 09:00:00 PST--2023-01-09 17:00:00 PST b 2023-01-09 11:00:00 PST--2023-01-09 12:30:00 PST

# insert reprex here
Error in setdiff.Interval(a, b) : 
  Cases 1 result in discontinuous intervals.

setdiff(b,a) resulted in output as b

Any suggestions, thank you

vspinu commented 1 year ago

We don't have this funtionality currently. If we are getting into setoperators with intervals then the big question how do we treat vector intervals. You are asking for element wise operation, but R set operations work on vectors.

DavisVaughan commented 1 year ago

I think you should use ivs for this, which has full support for both match-like set ops and pairwise set ops

library(ivs)

a <- iv(
  start = as.POSIXct("2023-01-09 09:00:00", tz = "America/Los_Angeles"),
  end = as.POSIXct("2023-01-09 17:00:00", tz = "America/Los_Angeles")
)
b <- iv(
  start = as.POSIXct("2023-01-09 11:00:00", tz = "America/Los_Angeles"),
  end = as.POSIXct("2023-01-09 12:30:00", tz = "America/Los_Angeles")
)

# Note that `b` is fully contained within `a`
a
#> <iv<datetime<America/Los_Angeles>>[1]>
#> [1] [2023-01-09 09:00:00, 2023-01-09 17:00:00)
b
#> <iv<datetime<America/Los_Angeles>>[1]>
#> [1] [2023-01-09 11:00:00, 2023-01-09 12:30:00)

# So this makes two intervals.
# It treats each vector (`a` and `b`) as one full set of intervals.
# `a` and `b` don't have to be the same length, i.e. they are compared in a match()-like way
# like setdiff()
iv_difference(a, b)
#> <iv<datetime<America/Los_Angeles>>[2]>
#> [1] [2023-01-09 09:00:00, 2023-01-09 11:00:00)
#> [2] [2023-01-09 12:30:00, 2023-01-09 17:00:00)

# This isn't allowed.
# Both `a` and `b` must be the same size, and removing `b` from `a` must
# result in a single interval, which isn't possible here.
iv_pairwise_difference(a, b)
#> Error in `iv_pairwise_difference()`:
#> ! Can't compute a difference when `y` is completely contained within `x`.
#> ℹ This would result in two distinct intervals for a single observation.
#> ℹ Location 1 contains this issue.

I'm not sure that lubridate should add much more functionality with intervals

vspinu commented 1 year ago

Indeed. Given that this is not a common request and that there is a very good tooling available it's not wise to pursue it here.