【问题标题】:Dynamically insert variables into a fable model using rlang使用 rlang 将变量动态插入到寓言模型中
【发布时间】:2020-04-23 15:09:16
【问题描述】:

我正在尝试将变量动态插入到寓言模型中。

数据

library(dplyr)
library(fable)
library(stringr)

df <- tsibbledata::aus_retail %>% 
  filter(State == "Victoria", Industry == "Food retailing") %>% 
  mutate(reg_test = rnorm(441, 5, 2),
         reg_test2 = rnorm(441, 5, 2))

请注意,tsibble 中可能包含不确定数量的回归量,但在此示例中,我只有两个(reg_testreg_test2)。所有回归量列都将以 reg_

开头

问题函数

我有一个函数,我想使用 fable 包将回归量列动态放入 ARIMA 模型中。

test_f <- function(df)  {
var_names <- str_subset(names(df), "reg_") %>% 
    paste0(collapse = "+")  
    test <- enquo(var_names)
df %>% 
  model(ARIMA(Turnover ~ !!test))
}

test_f(df)

# A mable: 1 x 3
# Key:     State, Industry [1]
  State    Industry      `ARIMA(Turnover ~ ~"reg_test+reg_tes~
  <chr>    <chr>         <model>                              
1 Victoria Food retaili~ <NULL model>                         
Warning message:
1 error encountered for ARIMA(Turnover ~ ~"reg_test+reg_test2")
[1] invalid model formula in ExtractVars

我知道它只是将字符串var_names 放入公式中,这是行不通的,但我不知道如何以正确的方式创建var_names 以使enquo() 正确。

我通读了准引用部分here 我搜索了 SO,但还没有找到答案。

This questionpasre_expr() 似乎越来越近了,但仍然不是我想要的。

我知道如果我有一个变量,我可以使用sym(),但我不知道会有多少个reg_ 变量,我想将它们全部包含在内。

预期输出

通过手动输入变量,我可以显示我期望的输出。

test <- df %>% 
  model(ARIMA(Turnover ~ reg_test + reg_test2))
test$`ARIMA(Turnover ~ reg_test + reg_test2)`[[1]]

Series: Turnover 
Model: LM w/ ARIMA(2,1,0)(0,1,2)[12] errors 

Coefficients:
          ar1      ar2     sma1     sma2  reg_test  reg_test2
      -0.6472  -0.3541  -0.4115  -0.0793   -0.0296    -0.6143
s.e.   0.0473   0.0479   0.0520   0.0446    0.5045     0.5273

sigma^2 estimated as 884.9:  log likelihood=-2058.04
AIC=4130.08   AICc=4130.35   BIC=4158.5

我还想象有一种更好的方法可以让我在 ARIMA 函数中制作公式。如果这也可以解决我的问题,那也可以。

感谢您的帮助!

【问题讨论】:

    标签: r rlang fable tidyverts


    【解决方案1】:

    您可能会让这变得比它需要的复杂一些。您可以通过执行as.formula(string) 将字符串转换为公式,因此只需将您的公式构建为字符串,将其转换为公式,然后将其提供给ARIMA。这是一个代表:

    library(dplyr)
    library(fable)
    library(stringr)
    
    df <- tsibbledata::aus_retail %>% 
      filter(State == "Victoria", Industry == "Food retailing") %>% 
      mutate(reg_test = rnorm(441, 5, 2),
             reg_test2 = rnorm(441, 5, 2))
    
    test_f <- function(df)  {
        var_names <- paste0(str_subset(names(df), "reg_"), collapse = " + ")
        mod <- model(df, ARIMA(as.formula(paste("Turnover ~", var_names))))
        unclass(mod[1, 3][[1]])[[1]]
    }
    
    test_f(df)
    #> Series: Turnover 
    #> Model: LM w/ ARIMA(2,1,0)(0,1,1)[12] errors 
    #> 
    #> Coefficients:
    #>           ar1     ar2     sma1  reg_test  reg_test2
    #>       -0.6689  -0.376  -0.4765    0.3363     1.0194
    #> s.e.   0.0448   0.045   0.0426    0.4978     0.5436
    #> 
    #> sigma^2 estimated as 883.1:  log likelihood=-2058.28
    #> AIC=4128.56   AICc=4128.76   BIC=4152.91
    

    reprex package (v0.3.0) 于 2020 年 4 月 23 日创建

    【讨论】:

    • 这太完美了!我确信我把它复杂化了。 as.formula 函数正是我想要的。我不需要unclass 部分。我只是想展示模型的外观,因为直到我真正查看模型之前,我无法判断我之前的尝试是否有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    相关资源
    最近更新 更多