You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中通过purrr::map传ARIMA/ETS字符串调用fabletools失效问题

失效原因
  • R本身完全支持把字符串形式的函数名做动态调用,不存在语法层面的阻碍
  • 你写的fable::x(Trips)是静态硬编码写法:R的::操作符是编译阶段就解析的,会直接去fable命名空间找字面叫x的函数,根本不会读取你存在变量x里的字符串值,所以必然运行报错
解决方案

要实现动态传模型名做批量拟合,核心是在运行期把字符串转成可调用的函数实体,以下两种写法完全适配fable生态的接口要求:

  • 用get()从指定包的命名空间取出函数实体:比如要取fable包里的ARIMA函数,就写get("ARIMA", envir = asNamespace("fable")),拿到函数后直接传参model_fn(Trips)即可
  • 用rlang::call2()动态构造函数调用表达式,再通过!!!展开传入model()接口,这种写法和fabletools对表达式的解析逻辑完全兼容

修正后的可运行代码

library(tidyverse)
library(fable)
library(fabletools)
library(tsibble)

tourism <- tsibble::tourism 
my.model.names <- c("ARIMA", "ETS")

# 逐次循环拟合的实现
fit_results <- map2(
  .x = my.model.names,
  .y = my.model.names,
  .f = function(model_name, result_name){
    # 从fable包命名空间动态取对应模型函数
    model_fun <- get(model_name, envir = asNamespace("fable"))
    # 正常拟合流程
    tourism %>%
      dplyr::filter(Region == "Adelaide") %>%
      fabletools::model(
        !!result_name := model_fun(Trips)
      )
  }
)

更高效的批量拟合写法

不需要逐次循环调用model(),fabletools本身支持一次传入多个模型表达式直接批量拟合,性能和可维护性更好:

# 动态构造所有模型的调用表达式
model_calls <- my.model.names %>%
  set_names() %>%
  map(~ rlang::call2(.x, quote(Trips)))

# 一次性传入model接口完成批量拟合
full_fit <- tourism %>%
  dplyr::filter(Region == "Adelaide") %>%
  fabletools::model(!!!model_calls)
注意事项
  • 不要硬写包名::变量名()的动态调用结构:::是静态解析的语法,不会读取运行期的变量值,所有动态取包内函数的操作都要通过get(envir = asNamespace(包名))实现
  • 不推荐用assign()把结果直接写到全局环境:会污染全局工作区,通过map()的返回值承接结果更稳定
  • 动态构造表达式的时候,用!! :=的命名写法可以自动匹配列表里的模型名作为拟合结果的列名,不需要手动调整结果名称

内容的提问来源于stack exchange,提问作者Christian Moczkowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 17:54:07