R使用fable和purrr为tsibble多序列按预设参数批量拟合ETS模型
问题原因
你遇到的两个报错/异常分别来自两个不同的错误用法:
- 模型拟合返回NA:
fable的ETS函数使用tidy非标准评估机制,你直接把变量trend.param/season.param传入trend()/season()时,函数会把变量名本身作为参数值,而不是读取变量存储的字符串,相当于实际运行的是trend("trend.param"),参数不合法导致拟合失败。 map_dfr调用报错:map系列函数默认遍历数据框的每一列,你把整个tsibble传给map_dfr时,相当于给自定义函数传入的是单个列向量,自然无法用[1, "RSSEAS"]取行列值。
解决方案
可以使用tsibble自带的分组机制+rlang注入运算符实现批量拟合,代码如下:
第一步:加载依赖包
library(tidyverse) library(tsibble) library(fable)
第二步:批量拟合与预测
推荐用更简洁的group_by_key+group_modify方案:
# 按tsibble预定义的key分组(每个分组对应一个SKU的全量数据+参数) result <- test.data %>% group_by_key() %>% group_modify(~{ # 提取当前分组的参数 trend_p <- .x$RSTREND[1] season_p <- .x$RSSEAS[1] # 用!!注入参数实际值到ETS公式中 .x %>% model(EXP = ETS(RSFQTY ~ trend(!!trend_p) + season(!!season_p))) %>% forecast(h = "3 years") })
运行后得到的result就是所有SKU的3年预测结果汇总表,自带分组键关联信息。
核心逻辑说明
!!是rlang提供的注入运算符,作用是在公式执行前,把变量存储的实际值替换到表达式中,彻底解决非标准评估下变量识别错误的问题。group_by_key()是tsibble的内置方法,会自动按你数据集定义的key(RSLITM、RSSEAS、RSTREND、RSMODE)分组,不需要手动写分组变量,也避免遗漏参数维度。group_modify会将每个分组的数据作为.x传入处理函数,返回的预测结果会自动和分组键拼接,不需要手动合并结果。
内容的提问来源于stack exchange,提问作者LauraDR
相关产品推荐
相关产品推荐

