R语言如何让函数参数同时作为列名变量与字符串值使用
问题场景
借助Excel管理多模型协变量纳入规则时,需要编写自定义函数提升批量遍历建模效率:函数接收模型名称作为唯一入参,需同时完成两个筛选动作:
- 从协变量规则表
modelinfo中,提取对应模型标记为纳入的协变量 - 从分析数据集
modeldata中,提取对应模型的子样本
初始代码仅实现了子样本筛选,无法将字符串格式的模型名参数识别为modelinfo的列名完成协变量提取,初始实现代码:
library(tidyverse) modelinfo <- tribble( ~covars,~`model 1`,~`model 2`, "x1" , 1 , 0, "x2" , 0 , 1 ) modeldata <- tribble( ~x1, ~x2, ~model, 3, 3, "model 1", 4, 1, "model 2", 1, 3, "model 1", 2, 4, "model 3" ) testfun <- function(modelnum){ covars <- modelinfo %>% filter({{modelnum}}==1) data <- modeldata %>% filter(model==modelnum) output=c(covars,data) return(output) } testfun(modelnum="model 1")
原因说明
tidyverse中常用的{{}}(curly-curly)运算符是为传递未加引号的列名设计的非标准引用工具,当入参是字符串格式的模型名时,它无法自动将字符串映射为对应列,因此协变量筛选逻辑失效。
实现方法
由于入参modelnum本身是字符串值,不需要做特殊的非标准引用转换:
- 子样本筛选部分原有字符串匹配逻辑无需修改,可正常运行
- 动态引用
modelinfo列时,使用tidyverse官方支持的.data代词,通过.data[[modelnum]]的格式即可按字符串索引到对应列
修正后的完整代码:
testfun <- function(modelnum){ # 按字符串动态引用列,筛选当前模型需要纳入的协变量 covars <- modelinfo %>% filter(.data[[modelnum]] == 1) %>% pull(covars) # 直接提取协变量名称为向量,方便后续建模调用 # 按字符串值匹配筛选当前模型的分析样本 analysis_data <- modeldata %>% filter(model == modelnum) # 用列表返回结果,避免不同类型对象合并出现格式异常 return( list( included_covariates = covars, analysis_sample = analysis_data ) ) } # 测试调用 testfun(modelnum = "model 1")
调用后返回结果:
- 纳入协变量:
x1 - 分析样本:
modeldata中model取值为model 1的2行观测
如果需要兼容传入未加引号模型名的写法(如testfun(model 1)),仅需在函数第一行添加modelnum <- rlang::as_name(rlang::enquo(modelnum)),将入参统一转换为字符串即可同时支持两种传参方式。
内容的提问来源于stack exchange,提问作者PaulB
相关产品推荐
相关产品推荐

