使用'model'函数调用model/variable预测时如何使用字符值?
How to use a character value when using the 'model' function to call the model/variable to forecast?
我的目标是创建一个函数,您可以在其中输入要预测的变量,然后对多种类型的模型(即 Naive、ETS、Mean)使用交叉验证,然后使用 'pull' 函数我将拉出具有最低 RMSE 的模型,然后我将预测最好的模型提前 1 步。
但是,我在倒数第二行遇到问题,在预测时使用字符值 'best.model' 作为模型的输入。 (错误在代码下方,您自己 运行)。
下面是更有意义的代码:
library(fpp3)
tsibble <- prices
function.fc <- function (variable) {
## cross validation models
cv.fit <- tsibble %>%
select(year, !!sym(variable)) %>%
stretch_tsibble(.init = 180, .step = 1) %>%
filter(.id != max(.id)) %>%
model(
MEAN(!!sym(variable)),
NAIVE(!!sym(variable))
)
## cv forecasts
cv.fc <- cv.fit %>%
forecast(h = 1)
## cv accuracy
cv.accuracy <- cv.fc %>%
accuracy(tsibble)
## pulls out the name of the best model
best.model <- cv.accuracy %>%
select(.model, .type, RMSE) %>%
arrange(RMSE) %>%
filter(row_number(RMSE) == 1) %>%
pull(.model)
## pulls out 1 step forecast
fc <- model(.data = tsibble, noquote(best.model)) %>%
forecast(h = 1)
return(fc)
}
function.fc("copper")
Error: Model definition(s) incorrectly created: noquote(best.model) Check that specified model(s) are model definitions. Run `rlang::last_error()` to see where the error occurred
如您所见,我已尝试使用 'unquote' 函数,但这仍然不起作用。
有人对使用什么有什么建议吗?我一直在努力寻找其他帖子来解决我的问题。
这是一个采用稍微不同方法的解决方案,首先定义一个命名的模型列表以供选择,然后使用 best.model
从列表中进行选择。这通常比陷入非标准评估的困境更可取。另请注意,我使用了 {{
到 'pipe' 不带引号的参数。您会注意到我还更改了一些对象名称。这是因为通常应避免在对象名称中使用 .
,以免与 R 中面向对象编程的 S3
系统混淆。
library(fpp3)
my_forecast <- function(data, variable) {
# Define a list of models with sensible names
models <- list(
mean = fable::MEAN,
naive = fable::NAIVE
)
## cross validation models
cv_fit <- data %>%
select(year, {{ variable }}) %>%
stretch_tsibble(.init = 180, .step = 1) %>%
filter(.id != max(.id)) %>%
model(
mean = models$mean({{ variable }}),
naive = models$naive({{ variable }})
)
## cv forecasts
cv_fc <- cv_fit %>%
forecast(h = 1)
## cv accuracy
cv_accuracy <- cv_fc %>%
accuracy(data)
## pulls out the name of the best model
best_model <- cv_accuracy %>%
select(.model, .type, RMSE) %>%
arrange(RMSE) %>%
filter(row_number() == 1) %>%
pull(.model)
## pulls out 1 step forecast
fc <- data %>%
model("{best_model}" := models[[best_model]]({{ variable }})) %>%
forecast(h = 1)
fc
}
my_forecast(prices, copper)
#> # A fable: 1 x 4 [1Y]
#> # Key: .model [1]
#> .model year copper .mean
#> <chr> <dbl> <dist> <dbl>
#> 1 naive 1998 N(2.6, 0.69) 2.59
由 reprex package (v2.0.0)
于 2021-05-11 创建
在函数的末尾,best.model
是一个字符串。例如,如果 variable = "copper"
,则您的函数会生成 best.model = "NAIVE(copper)"
。 model()
函数需要提供模型定义,而不是字符串。您可以使用 rlang::parse_expr()
将字符串解析为代码,然后对其求值以使用 rlang::eval_tidy()
.
生成模型定义
library(rlang)
library(fpp3)
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✓ tibble 3.1.0 ✓ tsibble 1.0.0
#> ✓ dplyr 1.0.5 ✓ tsibbledata 0.3.0
#> ✓ tidyr 1.1.3 ✓ feasts 0.2.1.9000
#> ✓ lubridate 1.7.10 ✓ fable 0.3.0.9000
#> ✓ ggplot2 3.3.3
best.model <- "NAIVE(copper)"
best.model <- eval_tidy(parse_expr(best.model))
best.model
#> <RW model definition>
model(prices, best.model)
#> # A mable: 1 x 1
#> best.model
#> <model>
#> 1 <NAIVE>
由 reprex package (v1.0.0)
于 2021-05-11 创建
我的目标是创建一个函数,您可以在其中输入要预测的变量,然后对多种类型的模型(即 Naive、ETS、Mean)使用交叉验证,然后使用 'pull' 函数我将拉出具有最低 RMSE 的模型,然后我将预测最好的模型提前 1 步。
但是,我在倒数第二行遇到问题,在预测时使用字符值 'best.model' 作为模型的输入。 (错误在代码下方,您自己 运行)。
下面是更有意义的代码:
library(fpp3)
tsibble <- prices
function.fc <- function (variable) {
## cross validation models
cv.fit <- tsibble %>%
select(year, !!sym(variable)) %>%
stretch_tsibble(.init = 180, .step = 1) %>%
filter(.id != max(.id)) %>%
model(
MEAN(!!sym(variable)),
NAIVE(!!sym(variable))
)
## cv forecasts
cv.fc <- cv.fit %>%
forecast(h = 1)
## cv accuracy
cv.accuracy <- cv.fc %>%
accuracy(tsibble)
## pulls out the name of the best model
best.model <- cv.accuracy %>%
select(.model, .type, RMSE) %>%
arrange(RMSE) %>%
filter(row_number(RMSE) == 1) %>%
pull(.model)
## pulls out 1 step forecast
fc <- model(.data = tsibble, noquote(best.model)) %>%
forecast(h = 1)
return(fc)
}
function.fc("copper")
Error: Model definition(s) incorrectly created: noquote(best.model) Check that specified model(s) are model definitions. Run `rlang::last_error()` to see where the error occurred
如您所见,我已尝试使用 'unquote' 函数,但这仍然不起作用。 有人对使用什么有什么建议吗?我一直在努力寻找其他帖子来解决我的问题。
这是一个采用稍微不同方法的解决方案,首先定义一个命名的模型列表以供选择,然后使用 best.model
从列表中进行选择。这通常比陷入非标准评估的困境更可取。另请注意,我使用了 {{
到 'pipe' 不带引号的参数。您会注意到我还更改了一些对象名称。这是因为通常应避免在对象名称中使用 .
,以免与 R 中面向对象编程的 S3
系统混淆。
library(fpp3)
my_forecast <- function(data, variable) {
# Define a list of models with sensible names
models <- list(
mean = fable::MEAN,
naive = fable::NAIVE
)
## cross validation models
cv_fit <- data %>%
select(year, {{ variable }}) %>%
stretch_tsibble(.init = 180, .step = 1) %>%
filter(.id != max(.id)) %>%
model(
mean = models$mean({{ variable }}),
naive = models$naive({{ variable }})
)
## cv forecasts
cv_fc <- cv_fit %>%
forecast(h = 1)
## cv accuracy
cv_accuracy <- cv_fc %>%
accuracy(data)
## pulls out the name of the best model
best_model <- cv_accuracy %>%
select(.model, .type, RMSE) %>%
arrange(RMSE) %>%
filter(row_number() == 1) %>%
pull(.model)
## pulls out 1 step forecast
fc <- data %>%
model("{best_model}" := models[[best_model]]({{ variable }})) %>%
forecast(h = 1)
fc
}
my_forecast(prices, copper)
#> # A fable: 1 x 4 [1Y]
#> # Key: .model [1]
#> .model year copper .mean
#> <chr> <dbl> <dist> <dbl>
#> 1 naive 1998 N(2.6, 0.69) 2.59
由 reprex package (v2.0.0)
于 2021-05-11 创建在函数的末尾,best.model
是一个字符串。例如,如果 variable = "copper"
,则您的函数会生成 best.model = "NAIVE(copper)"
。 model()
函数需要提供模型定义,而不是字符串。您可以使用 rlang::parse_expr()
将字符串解析为代码,然后对其求值以使用 rlang::eval_tidy()
.
library(rlang)
library(fpp3)
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✓ tibble 3.1.0 ✓ tsibble 1.0.0
#> ✓ dplyr 1.0.5 ✓ tsibbledata 0.3.0
#> ✓ tidyr 1.1.3 ✓ feasts 0.2.1.9000
#> ✓ lubridate 1.7.10 ✓ fable 0.3.0.9000
#> ✓ ggplot2 3.3.3
best.model <- "NAIVE(copper)"
best.model <- eval_tidy(parse_expr(best.model))
best.model
#> <RW model definition>
model(prices, best.model)
#> # A mable: 1 x 1
#> best.model
#> <model>
#> 1 <NAIVE>
由 reprex package (v1.0.0)
于 2021-05-11 创建