自定义recipes步骤step_hai_fourier prep阶段类型校验失败求助
排查自定义recipes步骤
step_hai_fourier的类型检查错误 问题描述
在开发自定义recipes步骤时,step_hai_fourier在prep阶段抛出类型不匹配错误,但测试用例中传入的变量b明确是数值类型(runif()生成的double类型)。错误提示如下:
Error in `prep()`: ! All variables for `step_hai_fourier` must be `numeric``integer` `double` classes.
问题根源
查看prep.step_hai_fourier中的类型检查逻辑:
if (any(value_data$type != "numeric")) { rlang::abort( paste0( "All variables for `step_hai_fourier` must be `numeric`", "`integer` `double` classes." ) ) }
在recipes >=1.0.0版本中,info$type字段对数值类型做了细分:
- integer类型变量的
type为"integer" - double类型变量的
type为"double" - 仅通过
as.numeric()转换的变量type才是"numeric"
测试用例中的b是runif()生成的double类型,因此value_data$type等于"double",不满足== "numeric"的条件,触发错误。
修复方案
方案1:修正类型判断逻辑
将类型检查改为判断变量类型是否属于允许的数值类型集合:
#' @export prep.step_hai_fourier <- function(x, training, info = NULL, ...) { col_names <- recipes::recipes_eval_select(x$terms, training, info) value_data <- info[info$variable %in% col_names, ] allowed_types <- c("numeric", "integer", "double") if (any(!value_data$type %in% allowed_types)) { rlang::abort( paste0( "All variables for `step_hai_fourier` must be of type ", paste(allowed_types, collapse = ", "), "." ) ) } step_hai_fourier_new( terms = x$terms, role = x$role, trained = TRUE, columns = col_names, scale_type = x$scale_type, period = x$period, order = x$order, skip = x$skip, id = x$id ) }
方案2:使用recipes内置类型检查函数(推荐)
使用recipes::check_type()函数,这是recipes包提供的标准类型检查工具,能自动处理类型判断并抛出规范错误:
#' @export prep.step_hai_fourier <- function(x, training, info = NULL, ...) { col_names <- recipes::recipes_eval_select(x$terms, training, info) # 用recipes内置函数检查类型,支持numeric/integer/double recipes::check_type(training[, col_names], types = c("numeric", "integer", "double")) step_hai_fourier_new( terms = x$terms, role = x$role, trained = TRUE, columns = col_names, scale_type = x$scale_type, period = x$period, order = x$order, skip = x$skip, id = x$id ) }
验证修复
修改后重新运行测试用例:
len_out <- 10 by_unit <- "month" start_date <- as.Date("2021-01-01") data_tbl <- tibble( date_col = seq.Date(from = start_date, length.out = len_out, by = by_unit), a = rnorm(len_out), b = runif(len_out) ) rec_obj <- recipe(a ~ ., data = data_tbl) %>% step_hai_fourier(b, scale_type = "sin") %>% step_hai_fourier(b, scale_type = "cos") %>% step_hai_fourier(b, scale_type = "sincos") # 现在prep可以正常执行 prepped_rec <- prep(rec_obj) # 烘焙数据 baked_data <- bake(prepped_rec, data_tbl)
内容的提问来源于stack exchange,提问作者MCP_infiltrator
相关产品推荐
相关产品推荐

