You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:23:23