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

Davis Vaughan d@v|@ @end|ng |rom po@|t@co
Fri Apr 28 17:12:27 CEST 2023


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.

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



More information about the R-devel mailing list