R语言创建recipes对象时动态传入列名、避免强制重命名问题问询
问题1 无需重命名的动态recipe构建方案
你不需要提前对数据集做重命名操作,核心利用两个特性即可实现动态列名适配:
- 用
reformulate()函数动态构建公式,无需硬编码响应变量列名 - recipes及扩展包原生支持tidyeval准引用规则,可以直接将用户传入的列名参数注入到各个step中
修改后的函数代码如下:
ts_auto_recipe <- function(.data, .date_col, .pred_col){ # * Tidyeval ---- date_col_var <- rlang::enquo(.date_col) pred_col_var <- rlang::enquo(.pred_col) # 提取列名字符串用于动态构建参数 date_col_name <- rlang::as_name(date_col_var) # * Checks ---- if(!is.data.frame(.data)){ stop(call. = FALSE, "You must supply a data.frame/tibble.") } if(rlang::quo_is_missing(date_col_var)){ stop(call. = FALSE, "The (.date_col) must be supplied.") } if(rlang::quo_is_missing(pred_col_var)){ stop(call. = FALSE, "The (.pred_col) must be supplied.") } # * Data ---- data_tbl <- tibble::as_tibble(.data) %>% dplyr::select( {{ date_col_var }}, {{ pred_col_var }}, dplyr::everything() ) # 移除了重命名步骤 # * Recipe Objects ---- # ** Base recipe ---- # 动态构建公式 rec_base_obj <- recipes::recipe( formula = reformulate(".", response = date_col_name), data = data_tbl ) # * Add Steps ---- # ** ts signature and normalize ---- rec_date_obj <- rec_base_obj %>% # 直接注入动态列名 timetk::step_timeseries_signature({{ date_col_var }}) %>% recipes::step_normalize( dplyr::contains("index.num"), # 动态生成匹配字符串 dplyr::contains(paste0(date_col_name, "_year")) ) # * Recipe List ---- rec_lst <- list( rec_base = rec_base_obj, rec_date = rec_date_obj ) # * Return ---- return(rec_lst) }
修改后的函数完全保留原始数据集列名,不会强制修改为固定名称,也不影响后续流程调用。
问题2 recipe列表打印乱码解决方案
该乱码是recipes包的print方法和R列表默认的长字符串截断逻辑冲突导致的编码异常,不属于代码逻辑错误,两种常用解决方式:
- 打印时遍历输出列表内的每个recipe对象,避免列表默认截断:
purrr::walk(rec_objs, print) - 调整R控制台打印宽度,避免长字符串被截断:
调整后直接打印整个列表也不会出现乱码。options(width = 200)
内容的提问来源于stack exchange,提问作者MCP_infiltrator
相关产品推荐
相关产品推荐

