1

I have a grouped time series with items and their category and I would like to make 6months sales forecasting. I would like to o use intermediate level (category) to make base forecasting because the stagionality and trends maybe are better valued. So i grouped my data for key, and i would like to use middle_out approch, the total sales use bottom up and single item are forected useing top down approach I'm using fabletools middle_out function, but when i try to make forecast it doesn't work this is my code:

library(reshape)
library(tidyverse)
library(tsibble)
library(dplyr)
library(fable)
library(fpp2)
library(forecast)

#read data from csv
#example dataset
set.seed(42)  ## for sake of reproducibility
n <- 6
data_example <- data.frame(Date=seq.Date(as.Date("2020-12-01"), as.Date("2021-05-01"), "month"),
                  No_=sample(1800:1830, n, replace=TRUE),
                  Category=rep(LETTERS[1:3], n),
                  Quantity=sample(18:24, n, replace=TRUE))


sell_full <- data_example %>% mutate(Month=yearmonth(Date)) %>% group_by(No_,Category, Month) %>% summarise(Quant = sum(Quantity), .groups = 'keep')
sell_full <- na.omit(sell_full)

#data


#conversion to tsibble for forecastings

sell_full <- as_tsibble(sell_full, key=c(No_, Category), index=Month)
sell_full <- sell_full %>% aggregate_key((Category/No_), Quant= sum(Quant)) 
#sell_full<- filter(sell_full, !is.na(sell_full$Quant))

sell_full <- sell_full %>% fill_gaps(Quant=0, .full=TRUE)

fit <- sell_full %>%model(ets = ETS(Quant~ error("A") + trend("A") + season("A")))%>% middle_out(split=1)

fc <- forecast(fit, h = "6 months", level=1,lambda="auto")

if I put method="mo" in forecast method as documentation says it return this error

Error in meanf(object, h = h, level = level, fan = fan, lambda = lambda,  : 
  unused argument (method = "mo")

if i doesn't put method info in forecast it return this error:

<error/vctrs_error_ptype2>
Error in `vec_compare()`:
! Can't combine `..1` <agg_vec> and `..2` <double>.
---
Backtrace:
  1. generics::forecast(fit, h = "6 months", level = 1, lambda = "auto")
  2. forecast:::forecast.default(fit, h = "6 months", level = 1, lambda = "auto")
  3. forecast:::forecast.ts(object, ...)
  4. forecast::meanf(...)
  5. forecast::BoxCox(x, lambda)
  6. forecast::BoxCox.lambda(x, lower = -0.9)
  7. fabletools:::Ops.lst_mdl(x, 0)
 11. fabletools:::map2(e1, e2, .Generic)
 12. base::mapply(.f, .x, .y, MoreArgs = list(...), SIMPLIFY = FALSE)
 13. vctrs:::`<=.vctrs_vctr`(dots[[1L]][[1L]], dots[[2L]][[1L]])
 14. vctrs::vec_compare(e1, e2)

The Documentions about it is very bad, someone can help me?

UPDATE: As someone suggest to me, I tried to remove some package, now my library are:

library(tsibble)
library(dplyr)
library(fable)
library(fpp3)
library(conflicted)

Now the error is changed. when I try to make forecast function I have this error:

Error in build_key_data_smat(key_data) : 
  argument "key_data" is missing, with no default

and if I put key_data = "Category" (Category is the split layer) the error is:

fc <- forecast(fit, h = "6 months",level=1,lambda="auto", key_data= "Category")
Error in -ncol(x) : invalid argument to unary operator
  • Can you make a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) and provide your data using `dput()`? – jrcalabrese Jan 08 '23 at 18:06
  • 1
    I think the problem is that you are loading packages that you don't need, which clash with other packages that you do need. Try without loading reshape, fpp2 or forecast. – Rob Hyndman Jan 09 '23 at 00:29
  • `library(tidyverse) library(fpp3)` will load all the tidyverse and tidyverts packages. You can test for clashes with `library(conflicted)`, which is super handy. – Isaiah Jan 09 '23 at 01:43
  • 1
    @Isaiah I add the new error string in the question's text, maybe forecast was the problem? Maybe forecast package doesn't need key_data but it try to compare some wrong format. It's better use forecast or fpp3? – Federico Silvestri Jan 12 '23 at 20:55
  • 1
    @jrcalabrese I add a dataframe creation thath it's look like my data. now the code is reproducibile – Federico Silvestri Jan 12 '23 at 22:08
  • Not sure why you have to supply key_data, given it's in the fit object, though. you do. The ncol error is because the code assumes that key_data is a vector, array, or data frame. I could do this via `x <- key_data(sell_full) |> unnest(cols = c(Category, No_, .rows))` and supply x as key_data. This gets you further along, but a new error occurs. `Error in UseMethod("forecast") : no applicable method for 'forecast' applied to an object of class "c('agg_vec', 'vctrs_rcrd', 'vctrs_vctr')"` I didn't get any namespace errors. Sharing in case this gives someone an idea. – Isaiah Jan 13 '23 at 08:14

1 Answers1

0
library(conflicted)
library(fpp3)
library(tidyverse)
n <- 6
data_example <- data.frame(Date = seq.Date(as.Date("2020-12-01"), as.Date("2021-05-01"), "month"),
                           No_ = sample(1800:1830, n, replace = TRUE),
                           Category = rep(LETTERS[1:3], n),
                           Quantity = sample(18:24, n, replace = TRUE))

sell_full <- data_example |> mutate(Month = yearmonth(Date)) |> group_by(No_,Category, Month) |> summarise(Quant = sum(Quantity), .groups = 'keep')
sell_full <- ungroup(sell_full)
sell_full <- as_tsibble(sell_full, key = c(No_, Category), index = Month)
sell_full <- sell_full %>% aggregate_key((Category/No_), Quant = sum(Quant))
sell_full <- sell_full %>% fill_gaps(Quant = 0, .full = TRUE)
fit <- sell_full %>% model(ets = ETS(Quant~ error("A") + trend("A")))

fc <- fabletools::forecast(fit, h = "6 months", lambda = "auto")

Thought I'd have a look at the code to generate sell_full.

Added an ungroup, took out the seasonal, and took out the middle_out. Runs now, and no longer asks for key_value. The ungroup, as it seemed that you were finished with the grouping. The seasonal as it was not supported by the data. The middle out as it would cause the prompt for key_value. Spent a bit of time on the middle_out leading to forecast asking for key_value, though, hence comment above.

This led me to try another way to do middle_out:

fit <- sell_full %>% model(ets = ETS(Quant~ error("A") + trend("A"))) |> reconcile(mo = middle_out(ets))

This runs fine. This idea came from fpp3 Hoping that this helps! :-)

Isaiah
  • 2,091
  • 3
  • 19
  • 28