In order to get the accuracy values from a forecast output vs. actual values in long format with many models and id's, I wanted to loop through the data and iteratively reduce the input object by using tail(input_object, -Forecast_horizon).
I would rather prefer some tidy approach to do this, because looping like this seems odd and crude.
library(forecast)
library(tibble)
testing_frame <- tibble(.value = rep(c(11,32,35,57,67,34),12),
test_value = rep(c(12,33,40,60,69,44),12),
id = rep(as.factor(c(rep(1,6),rep(2,6),rep(3,6),rep(4,6),rep(5,6),rep(6,6))),2),
model = as.character(c(rep(1,36),c(rep(2,36)))))
H = 6
iter = c(1:12)
datalist = list()
i = 1
for (i in iter) {
acc_all = forecast::accuracy(ts(head(testing_frame$.value,frequency = H),n=H),
ts(head(testing_frame$test_value,frequency = H),n=H))
testing_frame <- tail(testing_frame, -H)
acc_all_out = acc_all[,7]
datalist[[i]] <- acc_all_out
}
output = do.call(rbind, datalist)
A somewhat more succint approach would be to use data frame unpacking in
summarise()
to create new columns for each metric returned by accuracy()
:
library(tidyverse)
library(forecast)
testing_frame %>%
group_by(id, model) %>%
summarise(
accuracy(
ts(.value, frequency = H),
ts(test_value, frequency = H)
) %>% as_tibble()
)
#> # A tibble: 12 x 9
#> # Groups: id [6]
#> id model ME RMSE MAE MPE MAPE ACF1 `Theil's U`
#> <fct> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 2 1 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 3 2 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 4 2 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 5 3 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 6 3 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 7 4 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 8 4 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 9 5 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 10 5 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 11 6 1 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
#> 12 6 2 3.67 4.83 3.67 9.08 9.08 -0.114 0.128