0

I am using the fable package in R to forecast. I have successfully created forecasts for my units of interest (in this case metropolitan areas).

My issue is that, instead of using facet_wrap for autoplot, I want to generate forecast graphs for each metropolitan area (there are 64).
I tried the below code but got the associated error below.

forecastplots <- forecasts %>% group_by(Metro) %>% autoplot(fabledata) 
Error in `hilo()`:
! Objects of type `grouped_ts` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
• Objects of type `grouped_df` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
• Objects of type `tbl_ts` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
• Objects of type `tbl_df` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
• Objects of type `tbl` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
• Objects of type `data.frame` are not supported by `hilo()`, you can create a custom `hilo` with `new_hilo()`
Run `rlang::last_error()` to see where the error occurred.

I realize this is with groups and the hilo() function, but is there a workaround so I can generate all individual forecast graphs at once instead of having to type out each one with the filter == Metro command? I can do this but it will be time consuming and could also run into issues if my number of metros ever changes.

I may be missing something obvious with dplyr or fable but cannot figure it out.

I can generate the forecasts and the individual graphs but would like to be able to automatically generate all individual forecasts and be able to save these to an external pdf file.

1 Answers1

0

You can split up the fable and then plot and save each figure separately. For example:

library(fpp3)
#> -- Attaching packages -------------------------------------------- fpp3 0.4.0 --
#> v tibble      3.1.8          v tsibble     1.1.3     
#> v dplyr       1.1.0          v tsibbledata 0.4.1     
#> v tidyr       1.3.0          v feasts      0.3.0     
#> v lubridate   1.9.2          v fable       0.3.2.9000
#> v ggplot2     3.4.1
#> -- Conflicts ------------------------------------------------- fpp3_conflicts --
#> x lubridate::date()    masks base::date()
#> x dplyr::filter()      masks stats::filter()
#> x tsibble::intersect() masks base::intersect()
#> x tsibble::interval()  masks lubridate::interval()
#> x dplyr::lag()         masks stats::lag()
#> x tsibble::setdiff()   masks base::setdiff()
#> x tsibble::union()     masks base::union()
fbl <- tourism |> 
  # Just focusing on a few series to make the example more minimal
  filter(Region == "Melbourne") |>
  model(SNAIVE(Trips)) |> 
  forecast()

fbl |>
  # For each of the series
  group_by_key() |> 
  # Split the data into a list
  group_split() |> 
  # For each list element (series), autoplot it (you can also add ggsave here)
  lapply(autoplot, data = tourism)
#> [[1]]

#> 
#> [[2]]

#> 
#> [[3]]

#> 
#> [[4]]

Created on 2023-03-14 with reprex v2.0.2

You can also add more things into the lapply function for setting the labels based on the data's key values.

  • Thank you Mitchell, that was a great answer! It worked for my example, will have to adjust labeling in lapply but this will get me started. Thank you again! – John Meszaros Mar 14 '23 at 13:58
  • could you provide one last thing for me with this example: passing the keys to the titles. I followed your example above and split my data into a large list with elements. I am able to generate the graphs similar to above but am having trouble grabbing the key names for titles. Thanks again for the help! – John Meszaros Mar 14 '23 at 16:27
  • You can obtain the key variables (if you don't know them) with `tsibble::key_vars()`. Once you have them, you can obtain the key values for the current series with something like: `series_info <- data[1,tsibble::key_vars(data)]`. From here, it's up to you how you'd like to label them. For example, you could use: `series_name <- paste(names(series_info), unlist(series_info), sep = ": ", collapse = "; ")`. Then add it as the plot title with `ggplot2::labs(title = series_name)`. – Mitchell O'Hara-Wild Mar 15 '23 at 14:31