[Rd] range() for Date and POSIXct could respect `finite = TRUE`
Davis Vaughan
d@v|@ @end|ng |rom po@|t@co
Mon May 1 14:46:33 CEST 2023
Martin,
Yes, I missed that those have `Summary.*` methods, thanks!
Tweaking those to respect `finite = TRUE` sounds great. It seems like
it might be a little tricky since the Summary methods call
`NextMethod()`, and `range.default()` uses `is.numeric()` to determine
whether or not to apply `finite`. Because `is.numeric.Date()` is
defined, that always returns `FALSE` for Dates (and POSIXt). Because
of that, it may still be easier to just write a specific
`range.Date()` method, but I'm not sure.
-Davis
On Sat, Apr 29, 2023 at 4:47 PM Martin Maechler
<maechler using stat.math.ethz.ch> wrote:
>
> >>>>> Davis Vaughan via R-devel
> >>>>> on Fri, 28 Apr 2023 11:12:27 -0400 writes:
>
> > Hi all,
>
> > I noticed that `range.default()` has a nice `finite =
> > TRUE` argument, but it doesn't actually apply to Date or
> > POSIXct due to how `is.numeric()` works.
>
> Well, I think it would / should never apply:
>
> range() belongs to the "Summary" group generics (as min, max, ...)
>
> and there *are* Summary.Date() and Summary.POSIX{c,l}t() methods.
>
> Without checking further for now, I think you are indirectly
> suggesting to enhance these three Summary.*() methods so they do
> obey 'finite = TRUE' .
>
> I think I agree they should.
>
> Martin
>
> > ``` x <- .Date(c(0, Inf, 1, 2, Inf)) x #> [1] "1970-01-01"
> > "Inf" "1970-01-02" "1970-01-03" "Inf"
>
> > # Darn! range(x, finite = TRUE) #> [1] "1970-01-01" "Inf"
>
> > # What I want .Date(range(unclass(x), finite = TRUE)) #>
> > [1] "1970-01-01" "1970-01-03" ```
>
> > I think `finite = TRUE` would be pretty nice for Dates in
> > particular.
>
> > As a motivating example, sometimes you have ranges of
> > dates represented by start/end pairs. It is fairly natural
> > to represent an event that hasn't ended yet with an
> > infinite date. If you need to then compute a sequence of
> > dates spanning the full range of the start/end pairs, it
> > would be nice to be able to use `range(finite = TRUE)` to
> > do so:
>
> > ``` start <- as.Date(c("2019-01-05", "2019-01-10",
> > "2019-01-11", "2019-01-14")) end <-
> > as.Date(c("2019-01-07", NA, "2019-01-14", NA))
> > end[is.na(end)] <- Inf
>
> > # `end = Inf` means that the event hasn't "ended" yet
> > data.frame(start, end) #> start end #> 1 2019-01-05
> > 2019-01-07 #> 2 2019-01-10 Inf #> 3 2019-01-11 2019-01-14
> > #> 4 2019-01-14 Inf
>
> > # Create a full sequence along all days in start/end range
> > <- .Date(range(unclass(c(start, end)), finite = TRUE))
> > seq(range[1], range[2], by = 1) #> [1] "2019-01-05"
> > "2019-01-06" "2019-01-07" "2019-01-08" "2019-01-09" #> [6]
> > "2019-01-10" "2019-01-11" "2019-01-12" "2019-01-13"
> > "2019-01-14" ```
>
> > It seems like one option is to create a `range.Date()`
> > method that unclasses, forwards the arguments on to a
> > second call to `range()`, and then reclasses?
>
> > ``` range.Date <- function(x, ..., na.rm = FALSE, finite =
> > FALSE) { .Date(range(unclass(x), na.rm = na.rm, finite =
> > finite), oldClass(x)) } ```
>
> > This is similar to how `rep.Date()` works.
>
> > Thanks, Davis Vaughan
>
> > ______________________________________________
> > R-devel using r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list