如何在使用{targets}时用{box}编写所有函数?求解相关问题
使用{targets}配合{box}管理函数的最佳实践
一、简化模块函数的引入操作
- 批量导入模块:创建单独的脚本(如
src/import_modules.R),在其中集中用box::use()导入所有需要的模块和函数,然后在_targets.R中通过tar_source("src/import_modules.R")加载该脚本,避免在每个目标中重复编写导入语句。 - 自定义辅助函数:编写一个批量加载模块的函数(如
load_box_modules()),在函数内统一处理模块导入逻辑,只需在_targets.R中调用一次即可完成所有模块加载。
二、避免模块非函数改动导致目标过期
核心思路是让{targets}仅追踪目标实际依赖的函数代码,而非整个模块文件的变动,具体方法如下:
- 用
tarchetypes::tar_function()封装函数目标:将模块中的每个函数单独定义为{targets}的函数目标,这样只有当函数本身的代码修改时,依赖它的目标才会触发更新。示例代码如下:# 在_targets.R中 library(targets) library(tarchetypes) # 定义函数目标,仅追踪函数本身的哈希 tar_function( name = add_numbers, command = box::use(./modules/utils[add_numbers]) ) tar_target( name = result, command = add_numbers(2, 3), depends_on = add_numbers ) - 拆分模块文件:将纯函数代码和非函数内容(如注释、配置信息、临时调试代码)分开存放,纯函数模块仅保留函数定义,非函数改动放在独立文件中。这样纯函数模块只有在函数代码修改时才会影响目标的依赖哈希,非函数改动不会触发目标过期。
- 手动指定依赖范围:如果无法拆分模块,可在
tar_target()中通过tar_deps_raw()明确指定仅依赖模块中的特定函数,避免{targets}追踪整个模块文件的变动。
示例目录结构与代码
project/ ├── _targets.R ├── src/ │ ├── import_modules.R │ └── modules/ │ ├── utils.R # 仅存放纯函数 │ └── config.R # 存放配置、注释等非函数内容
src/modules/utils.R:
#' @export add_numbers <- function(a, b) { a + b } #' @export multiply_numbers <- function(a, b) { a * b }
src/import_modules.R:
box::use(./modules/utils[add_numbers, multiply_numbers]) box::use(./modules/config[*])
_targets.R:
library(targets) library(tarchetypes) # 加载批量导入脚本 tar_source("src/import_modules.R") # 定义函数目标 tar_function(add_numbers, box::use(./modules/utils[add_numbers])) tar_function(multiply_numbers, box::use(./modules/utils[multiply_numbers])) # 业务目标 tar_target(raw_data, c(1, 2, 3)) tar_target(processed_data, multiply_numbers(raw_data, 2)) tar_target(final_result, add_numbers(processed_data, 5))
内容的提问来源于stack exchange,提问作者glhrm
相关产品推荐
相关产品推荐

