R tidyeval/rlang环境下将函数参数c(x,y)转换为字符向量c("x","y")的方法
解决方案
核心实现(基于rlang包)
你不需要通过取子集再拿列名的迂回方案,直接用rlang内置的工具即可实现需求,分两类场景适配:
场景1:参数对应数据集列名(支持dplyr选择器语法)
用rlang::eval_select()实现,这是dplyr的select()函数的底层核心,不需要生成临时数据子集,直接返回匹配列的位置向量,向量名就是你需要的字符列名:
library(rlang) library(purrr) # 可选,用于批量处理符号 get_col_names <- function(data, cols) { # 捕获用户传入的表达式并求值 col_position <- eval_select(expr = enquo(cols), data = data) # 直接提取列名字符向量 return(names(col_position)) } # 测试用例,支持所有dplyr选择语法 get_col_names(mtcars, c(mpg, drat, starts_with("cy"))) # 输出: [1] "mpg" "drat" "cyl"
场景2:参数无需对应数据集列(通用符号转字符)
如果你的参数不需要和数据集列做校验,只是单纯要把用户输入的裸符号转换为字符向量,可直接捕获符号处理:
get_sym_names <- function(vars) { # 捕获用户传入的原始表达式 input_expr <- enexpr(vars) # 兼容c()包裹的多参数形式 if (is_call(input_expr, "c")) { sym_list <- as.list(input_expr)[-1] } else { sym_list <- list(input_expr) } # 批量转字符 return(map_chr(sym_list, as_string)) } # 测试用例,不需要传数据集也能运行 get_sym_names(c(mpg, drat, custom_var)) # 输出: [1] "mpg" "drat" "custom_var"
公式构造场景优化
针对你提到的构造模型公式的需求,不需要经过字符拼接的步骤,rlang支持直接构造公式对象,代码更简洁也更不易出错:
build_model_formula <- function(data, rhs_cols, lhs = NULL) { rhs_names <- get_col_names(data, {{ rhs_cols }}) # 批量转换为符号后拼接为公式右侧 rhs_expr <- expr(!!!syms(rhs_names)) # 生成公式对象 if (is.null(lhs)) { return(new_formula(lhs = NULL, rhs = rhs_expr)) } return(new_formula(lhs = sym(lhs), rhs = rhs_expr)) } # 测试用例 build_model_formula(mtcars, c(mpg, drat, cyl)) # 输出: ~mpg + drat + cyl build_model_formula(mtcars, c(mpg, drat), lhs = "wt") # 输出: wt ~ mpg + drat
内容的提问来源于stack exchange,提问作者Andrew Little
相关产品推荐
相关产品推荐

