循环输出到列表。有没有优雅的选择?
Loop output to list. Is there an elegant alternative?
为了从具有许多模型和 ID 的长格式的预测输出与实际值中获取准确度值,我想遍历数据并使用 tail(input_object, -Forecast_horizon).
我宁愿使用一些简洁的方法来执行此操作,因为这样的循环看起来很奇怪而且很粗糙。
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)
就 .value/test_value 而言,id/model 没有变化,因此每次迭代的输出都是相同的。但是,大概您的实际数据有这种变化。下面是一种按 id 和模型(即 12 组)分组的方法,然后使用 nest()
、map()
和 unnest_wider()
来获得结果
testing_frame %>% group_by(id, model) %>%
nest() %>%
mutate(acc = map(data,~accuracy(ts(.x$.value, frequency = H),ts(.x$test_value,frequency=H)))) %>%
unnest_wider(acc) %>%
rename_all(~c("id","model", "data","ME","RMSE","MAE","MPE","MAPE","ACF1", "Theil's U"))
输出:
id model data ME RMSE MAE MPE MAPE ACF1 `Theil's U`
<fct> <chr> <list> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
2 2 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
3 3 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
4 4 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
5 5 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
6 6 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
7 1 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
8 2 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
9 3 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
10 4 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
11 5 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
12 6 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
一种更简洁的方法是在
summarise()
为 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
为了从具有许多模型和 ID 的长格式的预测输出与实际值中获取准确度值,我想遍历数据并使用 tail(input_object, -Forecast_horizon).
我宁愿使用一些简洁的方法来执行此操作,因为这样的循环看起来很奇怪而且很粗糙。
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)
就 .value/test_value 而言,id/model 没有变化,因此每次迭代的输出都是相同的。但是,大概您的实际数据有这种变化。下面是一种按 id 和模型(即 12 组)分组的方法,然后使用 nest()
、map()
和 unnest_wider()
来获得结果
testing_frame %>% group_by(id, model) %>%
nest() %>%
mutate(acc = map(data,~accuracy(ts(.x$.value, frequency = H),ts(.x$test_value,frequency=H)))) %>%
unnest_wider(acc) %>%
rename_all(~c("id","model", "data","ME","RMSE","MAE","MPE","MAPE","ACF1", "Theil's U"))
输出:
id model data ME RMSE MAE MPE MAPE ACF1 `Theil's U`
<fct> <chr> <list> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
2 2 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
3 3 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
4 4 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
5 5 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
6 6 1 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
7 1 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
8 2 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
9 3 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
10 4 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
11 5 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
12 6 2 <tibble [6 x 2]> 3.67 4.83 3.67 9.08 9.08 -0.114 0.128
一种更简洁的方法是在
summarise()
为 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