tidyverts / tsibble

Tidy Temporal Data Frames and Tools
https://tsibble.tidyverts.org
GNU General Public License v3.0
527 stars 49 forks source link

fill_gaps() fails when week.start is not 1 #301

Closed jrauser closed 6 months ago

jrauser commented 10 months ago

When a calling fill_gaps() with keyed tsibble whose index is yearweek, and when week.start is not 1, fill_gaps() will fail with the error "Can't combine with different week_start"

library(tsibble)
#> 
#> Attaching package: 'tsibble'
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, union
options(lubridate.week.start = 7)
x <- tsibble(wk = yearweek(c("2023 W2", "2023 W5", "2023 W7", "2023 W2", "2023 W4", "2023 W7")), 
            thing=rep(c("a","b"), each=3), 
            value = 77,
            key="thing", 
            index="wk")
x
#> # A tsibble: 6 x 3 [1W]
#> # Key:       thing [2]
#>         wk thing value
#>     <week> <chr> <dbl>
#> 1 2023 W02 a        77
#> 2 2023 W05 a        77
#> 3 2023 W07 a        77
#> 4 2023 W02 b        77
#> 5 2023 W04 b        77
#> 6 2023 W07 b        77
fill_gaps(x, value=3)
#> Error in `vec_ptype2.yearweek.yearweek()`:
#> ! Can't combine <yearweek> with different `week_start`.
#> Backtrace:
#>      ▆
#>   1. ├─tsibble::fill_gaps(x, value = 3)
#>   2. └─tsibble:::fill_gaps.tbl_ts(x, value = 3)
#>   3.   ├─tsibble::scan_gaps(...)
#>   4.   └─tsibble:::scan_gaps.tbl_ts(...)
#>   5.     ├─dplyr::anti_join(ref_data, .data, by = c(key_vars(.data), idx_chr))
#>   6.     └─dplyr:::anti_join.data.frame(...)
#>   7.       └─dplyr:::join_filter(...)
#>   8.         └─dplyr:::join_cast_common(x_key, y_key, vars, error_call = error_call)
#>   9.           ├─rlang::try_fetch(...)
#>  10.           │ └─base::withCallingHandlers(...)
#>  11.           └─vctrs::vec_ptype2(x, y, x_arg = "", y_arg = "", call = error_call)
#>  12.             └─vctrs (local) `<fn>`()
#>  13.               └─tsibble:::vec_ptype2.yearweek.yearweek(x = x, y = y, x_arg = x_arg, y_arg = y_arg, call = call)
#>  14.                 └─rlang::abort("Can't combine <yearweek> with different `week_start`.")

# Notice that everything is fine when the tsibble doesn't have a key
y <- tsibble(wk = yearweek(c("2023 W2", "2023 W5", "2023 W7")), 
             value = 77,
             index="wk")
y
#> # A tsibble: 3 x 2 [1W]
#>         wk value
#>     <week> <dbl>
#> 1 2023 W02    77
#> 2 2023 W05    77
#> 3 2023 W07    77
fill_gaps(y, value=3)
#> # A tsibble: 6 x 2 [1W]
#>         wk value
#>     <week> <dbl>
#> 1 2023 W01    77
#> 2 2023 W02     3
#> 3 2023 W03     3
#> 4 2023 W04    77
#> 5 2023 W05     3
#> 6 2023 W06    77
Created on 2023-09-08 with [reprex v2.0.2](https://reprex.tidyverse.org/)
jrauser commented 10 months ago

The root cause is the same as with this issue.

Putting this patched function in my code works around the issue:

vec_ptype2.yearweek.yearweek <- function(x, y, ...) {
  if (attr(x, "week_start") != attr(y, "week_start")) {
    abort("Can't combine <yearweek> with different `week_start`.")
  }
  yearweek(NULL, week_start=attr(x, "week_start"))
}