rtibblefable-rtsibblefabletools

Can't convert a tsibble to a fable


I do not have a workaround for this at the moment, so desperately looking to solve this issue, no matter how cumbersome as long as my code is working again...

I want to coerce a tsibble to a fable object with:

as_fable

Documentation says that this is possible:

## S3 method for class 'tbl_ts'
as_fable(x, response, distribution, ...)

But when I specify the input parameter of this function I always get an error.

Example:

library(tsibbledata)
library(tsibble)
library(fable)
library(fabletools)

aus <- tsibbledata::hh_budget

fit <-  fabletools::model(aus, ARIMA = ARIMA(Debt))

fc_tsibble <- fit %>% 
              fabletools::forecast(., h = 2) %>%
              as_tibble(.) %>% 
              tsibble::as_tsibble(., key = c(Country, .model), index = Year)

fc_tsibble

# A tsibble: 8 x 5 [1Y]
# Key:       Country, .model [4]
  Country   .model  Year        Debt .mean
  <chr>     <chr>  <dbl>      <dist> <dbl>
1 Australia ARIMA   2017  N(215, 21)  215.
2 Australia ARIMA   2018  N(221, 63)  221.
3 Canada    ARIMA   2017   N(188, 7)  188.
4 Canada    ARIMA   2018  N(192, 21)  192.
5 Japan     ARIMA   2017 N(106, 3.8)  106.
6 Japan     ARIMA   2018 N(106, 7.6)  106.
7 USA       ARIMA   2017  N(109, 11)  109.
8 USA       ARIMA   2018  N(110, 29)  110.

class(fc_tsibble)

[1] "tbl_ts"     "tbl_df"     "tbl"        "data.frame"

Coercing to a fable leads to an error:

as_fable(fc_tsibble, response = .mean, distribution = Debt)

Error in eval_tidy(enquo(response)) : object '.mean' not found

Would be extremely grateful for any help!


Solution

  • It's not the most intuitive error message, but I have experienced this before with this function. You actually have to pass Debt to both arguments. I believe the error message references .mean because of an error thrown by an internal function.

    library(tsibbledata)
    library(tsibble)
    library(fable)
    library(fabletools)
    
    aus <- tsibbledata::hh_budget
    
    fit <-  fabletools::model(aus, ARIMA = ARIMA(Debt))
    
    fc_tsibble <- fit %>% 
      fabletools::forecast(., h = 2) %>%
      as_tibble(.) %>% 
      tsibble::as_tsibble(., key = c(Country, .model), index = Year)
    
    fc_tsibble
    #> # A tsibble: 8 x 5 [1Y]
    #> # Key:       Country, .model [4]
    #>   Country   .model  Year        Debt .mean
    #>   <chr>     <chr>  <dbl>      <dist> <dbl>
    #> 1 Australia ARIMA   2017  N(215, 21)  215.
    #> 2 Australia ARIMA   2018  N(221, 63)  221.
    #> 3 Canada    ARIMA   2017   N(188, 7)  188.
    #> 4 Canada    ARIMA   2018  N(192, 21)  192.
    #> 5 Japan     ARIMA   2017 N(106, 3.8)  106.
    #> 6 Japan     ARIMA   2018 N(106, 7.6)  106.
    #> 7 USA       ARIMA   2017  N(109, 11)  109.
    #> 8 USA       ARIMA   2018  N(110, 29)  110.
    
    fbl <- as_fable(fc_tsibble, response = "Debt", distribution = "Debt")
    
    fbl
    #> # A fable: 8 x 5 [1Y]
    #> # Key:     Country, .model [4]
    #>   Country   .model  Year        Debt .mean
    #>   <chr>     <chr>  <dbl>      <dist> <dbl>
    #> 1 Australia ARIMA   2017  N(215, 21)  215.
    #> 2 Australia ARIMA   2018  N(221, 63)  221.
    #> 3 Canada    ARIMA   2017   N(188, 7)  188.
    #> 4 Canada    ARIMA   2018  N(192, 21)  192.
    #> 5 Japan     ARIMA   2017 N(106, 3.8)  106.
    #> 6 Japan     ARIMA   2018 N(106, 7.6)  106.
    #> 7 USA       ARIMA   2017  N(109, 11)  109.
    #> 8 USA       ARIMA   2018  N(110, 29)  110.
    

    Created on 2020-09-28 by the reprex package (v0.3.0)

    It also works if you don't quote the distribution variable.

    as_fable(fc_tsibble, response = "Debt", distribution = Debt)
    #> # A fable: 8 x 5 [1Y]
    #> # Key:     Country, .model [4]
    #>   Country   .model  Year        Debt .mean
    #>   <chr>     <chr>  <dbl>      <dist> <dbl>
    #> 1 Australia ARIMA   2017  N(215, 21)  215.
    #> 2 Australia ARIMA   2018  N(221, 63)  221.
    #> 3 Canada    ARIMA   2017   N(188, 7)  188.
    #> 4 Canada    ARIMA   2018  N(192, 21)  192.
    #> 5 Japan     ARIMA   2017 N(106, 3.8)  106.
    #> 6 Japan     ARIMA   2018 N(106, 7.6)  106.
    #> 7 USA       ARIMA   2017  N(109, 11)  109.
    #> 8 USA       ARIMA   2018  N(110, 29)  110.
    

    Note that in the documentation it specifies that the response argument should be a character vector:

    response
    The character vector of response variable(s).

    However, if you do this you still get an error:

    as_fable(fc_tsibble, response = ".mean", distribution = Debt)
    #> Error: `fbl[[chr_dist]]` must be a vector with type <distribution>.
    #> Instead, it has type <distribution>.
    

    That error message is also unintuitive and somewhat conflicting. This is where I learned that you actually want to pass the distribution column to both arguments:

    as_fable(fc_tsibble, response = "Debt", distribution = Debt)
    #> # A fable: 8 x 5 [1Y]
    #> # Key:     Country, .model [4]
    #>   Country   .model  Year        Debt .mean
    #>   <chr>     <chr>  <dbl>      <dist> <dbl>
    #> 1 Australia ARIMA   2017  N(215, 21)  215.
    #> 2 Australia ARIMA   2018  N(221, 63)  221.
    #> 3 Canada    ARIMA   2017   N(188, 7)  188.
    #> 4 Canada    ARIMA   2018  N(192, 21)  192.
    #> 5 Japan     ARIMA   2017 N(106, 3.8)  106.
    #> 6 Japan     ARIMA   2018 N(106, 7.6)  106.
    #> 7 USA       ARIMA   2017  N(109, 11)  109.
    #> 8 USA       ARIMA   2018  N(110, 29)  110.
    
    as_fable(fc_tsibble, response = "Debt", distribution = "Debt")
    #> # A fable: 8 x 5 [1Y]
    #> # Key:     Country, .model [4]
    #>   Country   .model  Year        Debt .mean
    #>   <chr>     <chr>  <dbl>      <dist> <dbl>
    #> 1 Australia ARIMA   2017  N(215, 21)  215.
    #> 2 Australia ARIMA   2018  N(221, 63)  221.
    #> 3 Canada    ARIMA   2017   N(188, 7)  188.
    #> 4 Canada    ARIMA   2018  N(192, 21)  192.
    #> 5 Japan     ARIMA   2017 N(106, 3.8)  106.
    #> 6 Japan     ARIMA   2018 N(106, 7.6)  106.
    #> 7 USA       ARIMA   2017  N(109, 11)  109.
    #> 8 USA       ARIMA   2018  N(110, 29)  110.