tidyr icon indicating copy to clipboard operation
tidyr copied to clipboard

`full_seq.numeric()` should set `finite = TRUE`

Open DavisVaughan opened this issue 2 years ago • 1 comments

Right now you just get an error

> tidyr::full_seq(c(1, Inf), 1L)
Error in if (any(((x - rng[1])%%period > tol) & (period - (x - rng[1])%%period >  : 
  missing value where TRUE/FALSE needed

You most likely don't want to create an infinite sequence anyways.

This would be somewhat useful with the Date method in particular, as a way to generate a full sequence along the following start/end intervals:

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 "hasn't ended yet"
df <- tibble::tibble(start = start, end = end)
df
#> # A tibble: 4 × 2
#>   start      end       
#>   <date>     <date>    
#> 1 2019-01-05 2019-01-07
#> 2 2019-01-10 Inf       
#> 3 2019-01-11 2019-01-14
#> 4 2019-01-14 Inf

# Want a full sequence along range of start/end excluding infinite values
# `finite = TRUE` gives you the right range
range <- .Date(range(as.numeric(c(df$start, df$end)), finite = TRUE))
range
#> [1] "2019-01-05" "2019-01-14"

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"

# Ideally you'd just do:
# tidyr::full_seq(c(start, end), period = 1)

Created on 2023-04-28 with reprex v2.0.2.9000

DavisVaughan avatar Apr 28 '23 14:04 DavisVaughan

A few other edge cases to fix

> full_seq(c(1, NA, 2), 1)
Error in if (any(((x - rng[1])%%period > tol) & (period - (x - rng[1])%%period >  : 
  missing value where TRUE/FALSE needed

> full_seq(integer(), 1)
Error in if (period - ((rng[2] - rng[1])%%period) <= tol) { : 
  missing value where TRUE/FALSE needed
In addition: Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf

Also consider that full_seq.numeric() is fairly type unstable with regards to integer vs double output. Mainly something to keep in mind if we add some early exits for the length(x) <= 1 case to fix the above issue.

library(tidyr)

# unused `tol` so stays integer
x <- tidyr::full_seq(1:5, 1L, tol = 1e-6)
x
#> [1] 1 2 3 4 5
typeof(x)
#> [1] "integer"

# used `tol` converts to double
x <- tidyr::full_seq(1:5, 1L, tol = 1)
x
#> [1] 1 2 3 4 5 6
typeof(x)
#> [1] "double"

# used `tol` but stays integer
x <- tidyr::full_seq(1:5, 1L, tol = 1L)
x
#> [1] 1 2 3 4 5 6
typeof(x)
#> [1] "integer"

DavisVaughan avatar May 01 '23 17:05 DavisVaughan