phinterval() creates a new <phinterval> vector from start and end times.
A phinterval (think "potentially holey interval") is a span of time which may
contain gaps.
Arguments
- start, end
[POSIXct / POSIXlt / Date]A pair of datetime vectors to represent the endpoints of the spans.
startandendare recycled to a common length using vctrs-style recycling rules.- tzone
[character(1)]A time zone to display the
<phinterval>in. IftzoneisNULL(the default), then the time zone is taken from that ofstart.tzonecan be any non-NAstring, but unrecognized time zones (seeis_recognized_tzone()) will be formatted using"UTC"with a warning.- by
[vector / data.frame / NULL]An optional grouping vector or data frame. When provided,
start[i]andend[i]pairs are grouped byby[i], creating one phinterval element per unique value ofby. Overlapping or abutting spans within each group are merged. IfNULL(the default), eachstart/endpair creates a separate phinterval element.byis recycled to match the common length ofstartandend.bymay be any vector in the vctrs sense. Seevctrs::obj_is_vector()for details.- order_by
[TRUE / FALSE]Should the output be ordered by the values in
by? IfFALSE(the default), the output order matches the first appearance of each group inby. IfTRUE, the output is sorted by the unique values ofby. Only used whenbyis notNULL.
Value
When by = NULL, a <phinterval> vector the same length as the recycled
length of start and end.
When by is provided, a <phinterval> vector with one element per unique
value of by.
Details
The <phinterval> class is designed as a generalization of the
lubridate::interval(). While an <Interval> element represents a
single contiguous span between two fixed times, a <phinterval> element can
represent a time span that may be empty, contiguous, or disjoint (i.e. containing
gaps). Each element of a <phinterval> is stored as a (possibly empty) set of
non-overlapping and non-abutting time spans.
When by = NULL (the default), phinterval() creates scalar phinterval
elements, where each element contains a single time span from start[i] to
end[i]. This is equivalent to lubridate::interval():
interval(start, end, tzone = tzone) # <Interval> vector
phinterval(start, end, tzone = tzone) # <phinterval> vectorWhen by is provided, phinterval() groups the start/end pairs by the
values in by, creating phinterval elements that may contain multiple disjoint
time spans. Overlapping or abutting spans within each group are automatically
merged.
Differences from interval()
While phinterval() is designed as a drop-in replacement for
lubridate::interval(), there are three key differences regarding the
start and end arguments:
Stricter recycling:
phinterval()uses vctrs recycling rules instead of base R recycling. Length-1 vectors recycle to any length, but mismatched lengths (e.g., 2 vs 3) cause an error.No character inputs:
phinterval()does not accept character vectors forstartandend. Character starts and ends (e.g. "2021-01-01") must be converted to datetimes first usingas.POSIXct(),lubridate::ymd(), or a similar function.Standardized endpoints:
lubridate::interval()allows negative length spans whereend[i] < start[i].phinterval()flips the order of the i-th span's endpoints whenend[i] < start[i]to ensure that all spans are positive, similar tolubridate::int_standardize().
Examples
# Scalar phintervals (equivalent to interval())
phinterval(
start = as.Date(c("2000-01-01", "2000-02-01")),
end = as.Date(c("2000-02-01", "2000-03-01"))
)
#> <phinterval<UTC>[2]>
#> [1] {2000-01-01--2000-02-01} {2000-02-01--2000-03-01}
# Grouped phintervals with multiple spans per element
phinterval(
start = as.Date(c("2000-01-01", "2000-03-01", "2000-02-01")),
end = as.Date(c("2000-02-01", "2000-04-01", "2000-03-01")),
by = c(1, 1, 2)
)
#> <phinterval<UTC>[2]>
#> [1] {2000-01-01--2000-02-01, 2000-03-01--2000-04-01}
#> [2] {2000-02-01--2000-03-01}
# Overlapping spans are merged within groups
phinterval(
start = as.Date(c("2000-01-01", "2000-01-15")),
end = as.Date(c("2000-02-01", "2000-02-15")),
by = 1
)
#> <phinterval<UTC>[1]>
#> [1] {2000-01-01--2000-02-15}
# Empty phinterval
phinterval()
#> <phinterval<UTC>[0]>
# Specify time zone
phinterval(
start = as.Date("2000-01-01"),
end = as.Date("2000-02-01"),
tzone = "America/New_York"
)
#> <phinterval<America/New_York>[1]>
#> [1] {1999-12-31 19:00:00--2000-01-31 19:00:00}
