Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARIMA will not produce a weekly forecast when week_start != 1 #397

Open
jrauser opened this issue Jul 27, 2023 · 5 comments
Open

ARIMA will not produce a weekly forecast when week_start != 1 #397

jrauser opened this issue Jul 27, 2023 · 5 comments

Comments

@jrauser
Copy link

jrauser commented Jul 27, 2023

See reprex below. If week_start is set to 1 (the default) everything works as expected.

library(fable)
#> Loading required package: fabletools
library(tsibble)
#> 
#> Attaching package: 'tsibble'
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, union
dat<-tsibble(wk=make_yearweek(2023, 21:50, week_start=7), 
             x=rnorm(30,100,10),
             index=wk)
mable <- model(dat, ARIMA(x ~ pdq()))
fable <- mable %>% forecast(h=3)
#> Error in `mutate()`:
#> ℹ In argument: `ARIMA(x ~ pdq()) = (function (object, ...) ...`.
#> Caused by error in `vec_ptype2.yearweek.yearweek()`:
#> ! Can't combine <yearweek> with different `week_start`.
#> Backtrace:
#>      ▆
#>   1. ├─mable %>% forecast(h = 3)
#>   2. ├─generics::forecast(., h = 3)
#>   3. ├─fabletools:::forecast.mdl_df(., h = 3)
#>   4. │ └─dplyr::mutate_at(...)
#>   5. │   ├─dplyr::mutate(.tbl, !!!funs)
#>   6. │   └─dplyr:::mutate.data.frame(.tbl, !!!funs)
#>   7. │     └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#>   8. │       ├─base::withCallingHandlers(...)
#>   9. │       └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#>  10. │         └─mask$eval_all_mutate(quo)
#>  11. │           └─dplyr (local) eval()
#>  12. ├─generics (local) `<fn>`(...)
#>  13. └─fabletools:::forecast.lst_mdl(...)
#>  14.   └─fabletools:::mapply_maybe_parallel(...)
#>  15.     └─base::mapply(FUN = .f, ..., MoreArgs = MoreArgs, SIMPLIFY = SIMPLIFY)
#>  16.       ├─generics (local) `<fn>`(dots[[1L]][[1L]], dots[[2L]][[1L]], h = 3, point_forecast = `<named list>`)
#>  17.       └─fabletools:::forecast.mdl_ts(...)
#>  18.         ├─generics::forecast(...)
#>  19.         └─fable:::forecast.ARIMA(...)
#>  20.           └─vctrs:::`!=.vctrs_vctr`(...)
#>  21.             └─vctrs::vec_equal(e1, e2)
#>  22.               └─vctrs:::vec_cast_common_params(!!!args, .to = .ptype)
#>  23.                 └─vctrs:::vec_cast_common_opts(...)
#>  24.                   └─vctrs (local) `<fn>`()
#>  25.                     └─tsibble:::vec_ptype2.yearweek.yearweek(x = x, y = y, x_arg = x_arg, y_arg = y_arg, call = call)
#>  26.                       └─rlang::abort("Can't combine <yearweek> with different `week_start`.")
new_data <- tsibble(wk=make_yearweek(2023, 51:52, week_start=7), index=wk)
fable <- mable %>% forecast(new_data = new_data)
#> Error in `mutate()`:
#> ℹ In argument: `ARIMA(x ~ pdq()) = (function (object, ...) ...`.
#> Caused by error in `vec_ptype2.yearweek.yearweek()`:
#> ! Can't combine <yearweek> with different `week_start`.
#> Backtrace:
#>      ▆
#>   1. ├─mable %>% forecast(new_data = new_data)
#>   2. ├─generics::forecast(., new_data = new_data)
#>   3. ├─fabletools:::forecast.mdl_df(., new_data = new_data)
#>   4. │ └─dplyr::mutate_at(...)
#>   5. │   ├─dplyr::mutate(.tbl, !!!funs)
#>   6. │   └─dplyr:::mutate.data.frame(.tbl, !!!funs)
#>   7. │     └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#>   8. │       ├─base::withCallingHandlers(...)
#>   9. │       └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#>  10. │         └─mask$eval_all_mutate(quo)
#>  11. │           └─dplyr (local) eval()
#>  12. ├─generics (local) `<fn>`(...)
#>  13. └─fabletools:::forecast.lst_mdl(...)
#>  14.   └─fabletools:::mapply_maybe_parallel(...)
#>  15.     └─base::mapply(FUN = .f, ..., MoreArgs = MoreArgs, SIMPLIFY = SIMPLIFY)
#>  16.       ├─generics (local) `<fn>`(dots[[1L]][[1L]], dots[[2L]][[1L]], h = NULL, point_forecast = `<named list>`)
#>  17.       └─fabletools:::forecast.mdl_ts(...)
#>  18.         ├─generics::forecast(...)
#>  19.         └─fable:::forecast.ARIMA(...)
#>  20.           └─vctrs:::`!=.vctrs_vctr`(...)
#>  21.             └─vctrs::vec_equal(e1, e2)
#>  22.               └─vctrs:::vec_cast_common_params(!!!args, .to = .ptype)
#>  23.                 └─vctrs:::vec_cast_common_opts(...)
#>  24.                   └─vctrs (local) `<fn>`()
#>  25.                     └─tsibble:::vec_ptype2.yearweek.yearweek(x = x, y = y, x_arg = x_arg, y_arg = y_arg, call = call)
#>  26.                       └─rlang::abort("Can't combine <yearweek> with different `week_start`.")
@jrauser
Copy link
Author

jrauser commented Jul 27, 2023

Possibly related? tidyverts/tsibble#299

@jrauser
Copy link
Author

jrauser commented Jul 27, 2023

I looked into this a little bit, and the problem comes when the arima model object is created. It has a $tsp which has a $range, where the week_start hasn't been propagated. So the problem appears to be in whatever happens inside range() when a vector of yearweeks are given.

library(fable)
#> Loading required package: fabletools
library(tsibble)
#> 
#> Attaching package: 'tsibble'
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, union
dat<-tsibble(wk=make_yearweek(2023, 21:50, week_start=7), 
             x=rnorm(30,100,10),
             index=wk)
dat$wk[1]
#> <yearweek[1]>
#> [1] "2023 W21"
#> # Week starts on: Sunday
range(dat$wk)
#> <yearweek[2]>
#> [1] "2023 W20" "2023 W49"
#> # Week starts on: Monday

@jrauser
Copy link
Author

jrauser commented Jul 27, 2023

I think range just does something like c(min(dat$wk), max(dat$wk)), without propagating the attributes of the object.

The code that makes the range at L402 of arima.R needs to be aware of yearweek objects. The right thing might be to make a range() that knows how to operate properly on yearweeks.

@jrauser
Copy link
Author

jrauser commented Jul 27, 2023

Putting this in my code appears to paper over the problem:

range.yearweek <- function(x, ...) {
  yearweek(c(min(x), max(x)), week_start=attr(x, "week_start"))
}

I don't know how to write that code properly or I'd submit a PR.

@mitchelloharawild
Copy link
Member

Thanks for your careful investigation, resolving tidyverts/tsibble#300 should fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants