[Rd] range() for Date and POSIXct could respect `finite = TRUE`

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Sat Apr 29 22:47:28 CEST 2023


>>>>> 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