Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feature request/clarification: %within% for vectors of intervals #658

Closed
aetiologicCanada opened this issue Mar 26, 2018 · 4 comments
Closed
Labels
bug an unexpected problem or unintended behavior

Comments

@aetiologicCanada
Copy link

%within% works wonderfully for the stated use case: a %within% b,
where a is a date/datetime, and b is an single interval.

But sometimes the user has a vector of intervals, even an unknown number of intervals, and the question is whether is: a %within% B, where B is a vector of intervals (b1, b2, b3...)

Example:given a set of reward blackout dates for a frequent-flyer program, can I book a flight that leaves at a particular time?

A very good solution is found here:

thanks to:https://stackoverflow.com/questions/28682816/match-dates-against-date-intervals-holiday-periods-in-multiple-years

If we assume that df$datetimes holds the flight times , and blackouts$interval holds the blackout intervals we wish to include/exclude, with one record per blackout period:

apply(sapply(df$datetime, function(x) x %within% blackouts$interval),2,any)

works just fine, but its a bit "ugly" in that way that R can be ugly.

So, two suggestions: 1) make explicit within the %within% documentation that %within%t does not work across a vector of intervals 2) perhaps offer a nice purr-ized example of the above for this specific and I suspect common situation.

As always, thanks, thanks and thanks again for the tidyverse!

@vspinu
Copy link
Member

vspinu commented Mar 26, 2018

I am labeling this as a bug. All R functions should be vectorized whenever possible. Will have a look before next release.

@vspinu vspinu added the bug an unexpected problem or unintended behavior label Mar 26, 2018
@aetiologicCanada
Copy link
Author

aetiologicCanada commented Mar 26, 2018 via email

@aetiologicCanada
Copy link
Author

aetiologicCanada commented Mar 26, 2018

library(tidyverse)
library(lubridate)

testdate <- ymd("2015-01-02")
testdate

blackout<- c(interval(ymd("2014-12-30"), ymd("2014-12-31")))
blackout

testdate %within% blackout
# [1] FALSE

blackouts<- c(interval(ymd("2014-12-30"), ymd("2014-12-31")),
             interval(ymd("2014-12-30"), ymd("2015-01-03")))
blackouts

testdate %within% blackouts
# [1] FALSE  TRUE

#Note testdates is a multiple of blackouts
#
testdates <-c(ymd("2014-12-20", ymd("2014-12-30"), ymd("2015-01-01"), ymd("2015-01-03")))
testdates

testdates %within% blackouts
# [1] FALSE  TRUE FALSE  TRUE
# But 2015-01-01 is within blackout rule 2

testdates5 <-c(ymd("2014-12-20"), ymd("2014-12-30"), ymd("2015-01-01"), ymd("2015-01-03"), ymd("2015-05-05"))
testdates5

testdates5 %within% blackouts
#[1] FALSE  TRUE FALSE  TRUE FALSE
#Warning messages:
#  1: In as.numeric(a) - as.numeric(b@start) :
#  longer object length is not a multiple of shorter object length
#2: In as.numeric(a) - as.numeric(b@start) <= b@.Data :
#  longer object length is not a multiple of shorter object length
#3: In as.numeric(a) - as.numeric(b@start) :
#  longer object length is not a multiple of shorter object length
# but Jan 1 2015 is within blackouts[2]
# 
# 

@vspinu
Copy link
Member

vspinu commented Apr 10, 2018

Ok. I have misinterpreted your question. %within% works as expected (that is, it vectorizes over both, input vector and the interval vector).

Maybe we can extend %within% to work on list of intervals.

@vspinu vspinu closed this as completed in 87925a1 Apr 10, 2018
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue May 30, 2021
Version 1.7.10
==============

### NEW FEATURES

* `fast_strptime()` and `parse_date_time2()` now accept multiple formats and apply them in turn

### BUG FIXES

* [#926](tidyverse/lubridate#926) Fix incorrect division of intervals by months involving leap years
* Fix incorrect skipping of digits during parsing of the `%z` format

Version 1.7.9.2
===============

### NEW FEATURES

* [#914](tidyverse/lubridate#914) New `rollforward()` function
* [#928](tidyverse/lubridate#928) On startup lubridate now resets TZDIR to a proper directory when it is set to non-dir values like "internal" or "macOS" (a change introduced in R4.0.2)
* [#630](tidyverse/lubridate#630) New parsing functions `ym()` and `my()`

### BUG FIXES

* [#930](tidyverse/lubridate#930) `as.period()` on intervals now returns valid Periods with double fields (not integers)



Version 1.7.9
=============

### NEW FEATURES

* [#871](tidyverse/lubridate#893) Add `vctrs` support


### BUG FIXES

* [#890](tidyverse/lubridate#890) Correctly compute year in `quarter(..., with_year = TRUE)`
* [#893](tidyverse/lubridate#893) Fix incorrect parsing of abbreviated months in locales with trailing dot (regression in v1.7.8)
* [#886](tidyverse/lubridate#886) Fix `with_tz()` for POSIXlt objects
* [#887](tidyverse/lubridate#887) Error on invalid numeric input to `month()`
* [#889](tidyverse/lubridate#889) Export new dmonth function

Version 1.7.8
=============

### NEW FEATURES

* (breaking) Year and month durations now assume 365.25 days in a year consistently in conversion and constructors. Particularly `dyears(1) == years(1)` is now `TRUE`.
* Format and print methods for 0-length objects are more consistent.
* New duration constructor `dmonths()` to complement other duration constructors.
*
* `duration()` constructor now accepts `months` and `years` arguments.
* [#629](tidyverse/lubridate#629) Added `format_ISO8601()` methods.
* [#672](tidyverse/lubridate#672) Eliminate all partial argument matches
* [#674](tidyverse/lubridate#674) `as_date()` now ignores the `tz` argument
* [#675](tidyverse/lubridate#675) `force_tz()`, `with_tz()`, `tz<-` convert dates to date-times
* [#681](tidyverse/lubridate#681) New constants `NA_Date_` and `NA_POSIXct_` which parallel built-in primitive constants.
* [#681](tidyverse/lubridate#681) New constructors `Date()` and `POSIXct()` which parallel built-in primitive constructors.
* [#695](tidyverse/lubridate#695) Durations can now be compared with numeric vectors.
* [#707](tidyverse/lubridate#707) Constructors return 0-length inputs when called with no arguments
* [#713](tidyverse/lubridate#713) (breaking) `as_datetime()` always returns a `POSIXct()`
* [#717](tidyverse/lubridate#717) Common generics are now defined in `generics` dependency package.
* [#719](tidyverse/lubridate#719) Negative Durations are now displayed with leading `-`.
* [#829](tidyverse/lubridate#829) `%within%` throws more meaningful messages when applied on unsupported classes
* [#831](tidyverse/lubridate#831) Changing hour, minute or second of Date object now yields POSIXct.
* [#869](tidyverse/lubridate#869) Propagate NAs to all internal components of a Period object

### BUG FIXES

* [#682](tidyverse/lubridate#682) Fix quarter extraction with small `fiscal_start`s.
* [#703](tidyverse/lubridate#703) `leap_year()` works with objects supported by `year()`.
* [#778](tidyverse/lubridate#778) `duration()/period()/make_difftime()` work with repeated units
* `c.Period` concatenation doesn't fail with empty components.
* Honor `exact = TRUE` argument in `parse_date_time2`, which was so far ignored.

Version 1.7.4
=============

### NEW FEATURES

* [#658](tidyverse/lubridate#658) `%within%` now accepts a list of intervals, in which case an instant is checked if it occurs within any of the supplied intervals.

### CHANGES

* [#661](tidyverse/lubridate#661) Throw error on invalid multi-unit rounding.
* [#633](tidyverse/lubridate#633) `%%` on intervals relies on `%m+` arithmetic and doesn't produce NAs when intermediate computations result in non-existent dates.
* `tz()` always returns "UTC" when `tzone` attribute cannot be inferred.

### BUG FIXES

* [#664](tidyverse/lubridate#664) Fix lookup of period functions in `as.period`
* [#649](tidyverse/lubridate#664) Fix system timezone memoization

Version 1.7.3
=============

### BUG FIXES

* [#643](tidyverse/lubridate#643), [#640](tidyverse/lubridate#640), [#645](tidyverse/lubridate#645) Fix faulty caching of system timezone.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

2 participants