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

为parsnip模型规格添加自定义类后工作流拟合报错求助

自定义模型类导致工作流拟合报错问题

我编写了生成模型规格的函数internal_make_spec_tbl,目的是给模型对象添加自定义类,以此实现泛型工作流与拟合函数的方法分发——比如像multilevelmod里的gee模型,这类模型需要特殊的工作流构建方式,我希望通过internal_make_wflw_tbl.gee_linear_reg这类方法来适配。

函数代码如下:

internal_make_spec_tbl <- function(.model_tbl){

  # Tidyeval ----
  model_tbl <- .model_tbl

  # Checks ----
  if (!inherits(model_tbl, "tidyaml_base_tbl")){
    rlang::abort(
      message = "The model tibble must come from the make base tbl function.",
      use_cli_format = TRUE
    )
  }

  # Manipulation
  model_factor_tbl <- model_tbl |>
    dplyr::mutate(.model_id = dplyr::row_number() |>
                    forcats::as_factor()) |>
    dplyr::select(.model_id, dplyr::everything())

  # Make a group split object list
  models_list <- model_factor_tbl |>
    dplyr::group_split(.model_id)

  # Make the Workflow Object using purrr imap
  model_spec <- models_list |>
    purrr::imap(
      .f = function(obj, id){

        # Pull the model column and then pluck the model
        pe <- obj |> dplyr::pull(2) |> purrr::pluck(1)
        pm <- obj |> dplyr::pull(3) |> purrr::pluck(1)
        pf <- obj |> dplyr::pull(4) |> purrr::pluck(1)

        ret <- match.fun(pf)(mode = pm, engine = pe)

        # Add parsnip engine and fns as class
        class(ret) <- c(
          class(ret),
          paste0(base::tolower(pe), "_", base::tolower(pf))
        )

        # Return the result
        attributes(ret)$.tidyaml_mod_class <- paste0(base::tolower(pe), "_", base::tolower(pf))
        return(ret)
      }
    )

  # Return
  # Make sure to return as a tibble
  model_spec_ret <- model_factor_tbl |>
    dplyr::mutate(model_spec = model_spec)  |>
    dplyr::mutate(.model_id = as.integer(.model_id))

  return(model_spec_ret)
}

但给模型对象添加自定义类后,执行工作流拟合时出现了grep()参数长度>1的错误。

正常运行情况(未添加自定义类)

library(tidyAML)
library(dplyr)
library(recipes)

# 当前正常运行逻辑
mod_spec_tbl <- fast_regression_parsnip_spec_tbl(
 .parsnip_eng = c("lm","glm","gee"),
 .parsnip_fns = "linear_reg"
)

rec_obj <- recipe(mpg ~ ., data = mtcars)
splits_obj <- create_splits(mtcars, "initial_split")

mod_tbl <- mod_spec_tbl |>
 mutate(wflw = internal_make_wflw(mod_spec_tbl, rec_obj))
Error in `.f()`:
! parsnip could not locate an implementation for `linear_reg` regression model specifications
  using the `gee` engine.
ℹ The parsnip extension package multilevelmod implements support for this specification.
ℹ Please install (if needed) and load to continue.


internal_make_fitted_wflw(mod_tbl, splits_obj)
Error in UseMethod("fit"): no applicable method for 'fit' applied to an object of class "NULL"

[[1]]
══ Workflow [trained] ═════════════════════════════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: linear_reg()

── Preprocessor ───────────────────────────────────────────────────────────────────────────────────────
0 Recipe Steps

── Model ──────────────────────────────────────────────────────────────────────────────────────────────

Call:
stats::lm(formula = ..y ~ ., data = data)

Coefficients:
(Intercept)          cyl         disp           hp         drat           wt         qsec  
   -9.56517      0.29867      0.03116     -0.01767      2.84035     -3.41110      0.86809  
         vs           am         gear         carb  
    2.58991      4.01435      2.23389     -0.84017  


[[2]]
NULL

[[3]]
══ Workflow [trained] ═════════════════════════════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: linear_reg()

── Preprocessor ───────────────────────────────────────────────────────────────────────────────────────
0 Recipe Steps

── Model ──────────────────────────────────────────────────────────────────────────────────────────────

Call:  stats::glm(formula = ..y ~ ., family = stats::gaussian, data = data)

Coefficients:
(Intercept)          cyl         disp           hp         drat           wt         qsec  
   -9.56517      0.29867      0.03116     -0.01767      2.84035     -3.41110      0.86809  
         vs           am         gear         carb  
    2.58991      4.01435      2.23389     -0.84017  

Degrees of Freedom: 23 Total (i.e. Null);  13 Residual
Null Deviance:      972.7 
Residual Deviance: 83.84    AIC: 122.1

上述错误符合预期,因为未加载multilevelmod包。

添加自定义类后的报错情况

mod_tbl <- make_regression_base_tbl()
mod_tbl <- mod_tbl |>
  filter(
    .parsnip_engine %in% c("lm", "glm", "gee") &
      .parsnip_fns == "linear_reg"
  )

class(mod_tbl) <- c("tidyaml_mod_spec_tbl", class(mod_tbl))

mod_spec_tbl <- internal_make_spec_tblv2(mod_tbl)
mod_wflw_tbl <- mod_spec_tbl |>
  mutate(wflw = internal_make_wflw(mod_spec_tbl, rec_obj))
Error in `.f()`:
! parsnip could not locate an implementation for `linear_reg` regression model specifications
  using the `gee` engine.
ℹ The parsnip extension package multilevelmod implements support for this specification.
ℹ Please install (if needed) and load to continue.


internal_make_fitted_wflw(mod_wflw_tbl, splits_obj)
Error in `rlang::env_get()`:
! `nm` must be a string.

Error in UseMethod("fit"): no applicable method for 'fit' applied to an object of class "NULL"

Error in `rlang::env_get()`:
! `nm` must be a string.

[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

Warning messages:
1: In grep(model, env_obj, value = TRUE) :
  argument 'pattern' has length > 1 and only the first element will be used
2: In grep(model, env_obj, value = TRUE) :
  argument 'pattern' has length > 1 and only the first element will be used

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:50:09