问题
I am trying to fit some time series using the R packages tsibble and fable, the still-under-construction replacement for the redoubtable Rob Hyndman's forecast package. The series are all combined into one tsibble, which I then fit with ARIMA, a function which replaces, among other things, forecast::auto.arima.
I use map_at, first to iterate over all the elements except the Date, and then again to extract the model information from the models that have been fit to each series using fablelite::components. (A lot of the fable functions are really in fablelite).
This fails, apparently because components expects an object of class mdl_df and my model objects have class mdl_defn
Here is a toy example that (almost) reproduces the error:
library(tidyverse)
library(tsibble)
library(fable)
set.seed(1)
ar1 <- arima.sim(model=list(ar=.6), n=10)
ma1 <- arima.sim(model=list(ma=0.4), n=10)
Date <- c(ymd("2019-01-01"):ymd("2019-01-10"), ymd("2019-01-01"):ymd("2019-01-10"))
tb <- tibble(Date, ar1, ma1)
# Fit the whole series
tb_all <- tb %>%
map_at(.at = c("ar1", "ma1"), .f = ARIMA)
names(arima_all[2:3])<- c("ar1", "ma1")
# Extract model components
tb_components <- tb %>%
map_at(.at = c("ar1", "ma1"),
.f = fablelite::components)
Note that in this toy, like my real data, time is in 5-day weeks with missing weekends
In this toy example, the the error message says the components function rejects list elements on grounds there is no method for class ts. In my real case, which uses longer series and more of them, but is to my eye otherwise identical, elements are rejected because they are of class mdl_defn. Note that if I examine the 2nd and third elements of tb_all with str( ), they also display as of Classes 'mdl_defn', 'R6' Not sure where the ts in the error message comes from.
回答1:
Here is an example that hopefully does something like what you want.
First, you need to create a tsibble:
library(tidyverse)
library(tsibble)
library(fable)
library(lubridate)
set.seed(1)
ar1 <- arima.sim(model=list(ar=.6), n=30)
ma1 <- arima.sim(model=list(ma=0.4), n=30)
Date <- ymd(paste0("2019-01-",1:30))
tb <- bind_cols(Date=Date, ar1=ar1, ma1=ma1) %>%
gather("Series", "value", -Date) %>%
as_tsibble(index=Date, key=Series)
tb
#> # A tsibble: 60 x 3 [1D]
#> # Key: Series [2]
#> Date Series value
#> <date> <chr> <dbl>
#> 1 2019-01-01 ar1 -2.07
#> 2 2019-01-02 ar1 -0.118
#> 3 2019-01-03 ar1 -0.116
#> 4 2019-01-04 ar1 -0.0856
#> 5 2019-01-05 ar1 0.892
#> 6 2019-01-06 ar1 1.36
#> 7 2019-01-07 ar1 1.41
#> 8 2019-01-08 ar1 1.76
#> 9 2019-01-09 ar1 1.84
#> 10 2019-01-10 ar1 1.18
#> # … with 50 more rows
This contains two series: ar1 and ma1 over the same 30 days.
Next you can fit ARIMA models to both series in one simple function.
tb_all <- tb %>% model(arima = ARIMA(value))
tb_all
#> # A mable: 2 x 2
#> # Key: Series [2]
#> Series arima
#> <chr> <model>
#> 1 ar1 <ARIMA(0,0,2)>
#> 2 ma1 <ARIMA(0,0,0) w/ mean>
Finally, it is not clear what you are trying to extract using components(), but perhaps one of the following does what you want:
tidy(tb_all)
#> # A tibble: 3 x 7
#> Series .model term estimate std.error statistic p.value
#> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 ar1 arima ma1 0.810 0.198 4.09 0.000332
#> 2 ar1 arima ma2 0.340 0.181 1.88 0.0705
#> 3 ma1 arima constant 0.295 0.183 1.61 0.118
glance(tb_all)
#> # A tibble: 2 x 9
#> Series .model sigma2 log_lik AIC AICc BIC ar_roots ma_roots
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <list> <list>
#> 1 ar1 arima 0.695 -36.4 78.9 79.8 83.1 <cpl [0]> <cpl [2]>
#> 2 ma1 arima 1.04 -42.7 89.4 89.8 92.2 <cpl [0]> <cpl [0]>
augment(tb_all)
#> # A tsibble: 60 x 6 [1D]
#> # Key: Series, .model [2]
#> Series .model Date value .fitted .resid
#> <chr> <chr> <date> <dbl> <dbl> <dbl>
#> 1 ar1 arima 2019-01-01 -2.07 -0.515 -1.56
#> 2 ar1 arima 2019-01-02 -0.118 -1.21 1.09
#> 3 ar1 arima 2019-01-03 -0.116 0.511 -0.627
#> 4 ar1 arima 2019-01-04 -0.0856 -0.155 0.0690
#> 5 ar1 arima 2019-01-05 0.892 -0.154 1.05
#> 6 ar1 arima 2019-01-06 1.36 0.871 0.486
#> 7 ar1 arima 2019-01-07 1.41 0.749 0.659
#> 8 ar1 arima 2019-01-08 1.76 0.699 1.06
#> 9 ar1 arima 2019-01-09 1.84 1.09 0.754
#> 10 ar1 arima 2019-01-10 1.18 0.973 0.206
#> # … with 50 more rows
To see model outputs in the traditional way, use report():
tb_all %>% filter(Series=='ar1') %>% report()
#> Series: value
#> Model: ARIMA(0,0,2)
#>
#> Coefficients:
#> ma1 ma2
#> 0.8102 0.3402
#> s.e. 0.1982 0.1809
#>
#> sigma^2 estimated as 0.6952: log likelihood=-36.43
#> AIC=78.86 AICc=79.78 BIC=83.06
tb_all %>% filter(Series=='ma1') %>% report()
#> Series: value
#> Model: ARIMA(0,0,0) w/ mean
#>
#> Coefficients:
#> constant
#> 0.2950
#> s.e. 0.1833
#>
#> sigma^2 estimated as 1.042: log likelihood=-42.68
#> AIC=89.36 AICc=89.81 BIC=92.17
来源:https://stackoverflow.com/questions/57175973/r-forecasting-multiple-time-series-with-fable-tsibble-and-map