R包自定义工作流函数中tar_script()参数求值问题求助
解决tar_script()封装函数时参数无法求值的问题
当你把targets工作流封装成R包函数时,tar_script()不会自动将传入的参数(比如controller、file_path)转换成实际代码,而是保留eval(...)形式,这是因为它默认按表达式字面量处理输入。要解决这个问题,核心是把动态参数转换成可直接写入脚本的R代码文本,具体做法如下:
- 将参数转为代码表达式/字符串:用
rlang::enexpr()捕获参数的原始表达式,或者用rlang::expr_text()/deparse()把对象转换成对应的代码文本字符串,确保tar_script()写入文件时是实际的函数调用代码,而非eval引用。 - 用非标准求值注入参数:在tar_script()的代码块中,用
!!(bang-bang操作符)将捕获到的表达式直接注入,替代原本的参数占位符。
错误写法(参数保留eval形式)
run_workflow <- function(controller, file_path) { tar_script({ library(targets) library(crew) tar_option_set(controller = controller) list( tar_target(data, read.csv(file_path)) ) }, ask = FALSE) tar_make() }
正确写法(参数转为实际代码)
run_workflow <- function(controller, file_path) { tar_script({ library(targets) library(crew) # 用!!注入controller的原始表达式 tar_option_set(controller = !!rlang::enexpr(controller)) # 字符串参数直接用!!注入会自动保留引号 list( tar_target(data, read.csv(!!file_path)) ) }, ask = FALSE) tar_make() }
这里的关键是rlang::enexpr(),它会直接捕获传入参数的原始表达式(比如crew_controller_local(workers = 4)),而非求值后的对象,再通过!!将表达式注入到tar_script的代码块中,生成的_targets.R文件里就会是实际的函数调用代码,不再是eval(controller)。
额外注意点
- 若参数是字符串类型(如file_path),直接用
!!注入会自动保留引号,无需额外处理; - 若参数是复杂自定义对象,
enexpr()比expr_text()更直接,能完整保留表达式结构; - 测试时可先调用
tar_script()生成文件后打开查看,确认参数是否正确替换为实际代码。
内容的提问来源于stack exchange,提问作者Derek Corcoran
相关产品推荐
相关产品推荐

