
Pipelines with Smart Caching using targets
Generate
_targets.R, run with dynamic parallelism, and monitor with
sus_rap_targets() and sus_rap_make()
Dr. Max Anjos
17 October, 2026
Source:vignettes/rap-02-targets.Rmd
rap-02-targets.RmdIntroduction — Why use targets?
Epidemiological analyses with climate data are rarely linear. Over the course of a research cycle, it’s common to change a CID-10 filter, swap the climate aggregation window, or add a new state to the dataset. Without a smart caching system, any of these changes forces a re-run of the entire pipeline — including costly steps such as the DATASUS download, encoding standardization, and the spatial join, which can take hours.
The targets package (Landau, 2021) solves this problem
with automatic dependency tracking: each pipeline step
is a target, and targets only re-executes the
targets whose inputs changed since the last run. Intermediate results
are cached in the _targets/ directory, ready to be loaded
instantly.
The sus_rap_targets() function bridges
climasus4r’s RAP objects with the targets
ecosystem, automatically generating the _targets.R file
with all the necessary structure. sus_rap_make() then runs
this pipeline reproducibly, with support for parallelism and
monitoring.
Functions covered in this tutorial
This tutorial covers two exported functions from
climasus4r:
| Function | Description |
|---|---|
sus_rap_targets() |
Generates the _targets.R file from a RAP object |
sus_rap_make() |
Runs the pipeline via targets::tar_make()
|
Prerequisites
Installing dependencies
The targets package is listed under
Suggests in climasus4r. Install it before
using the functions in this tutorial:
# Necessary dependencies
install.packages("targets")
install.packages("tarchetypes") # optional: additional helpersStarting point: the RAP object
The functions in this tutorial operate on a RAP
object — a pipeline expression created with
climasus4r’s functions. You can obtain it in two ways:
library(climasus4r)
# Option A: read an existing RAP (created with sus_rap_export())
rap <- sus_rap_read("analise_dengue_nordeste.R")
# Option B: use a pipeline expression directly
pipeline <- quote(
sus_data_import(uf = c("CE", "RN", "PB", "PE", "AL"),
years = 2018:2022, system = "SINAN") |>
sus_data_clean_encoding() |>
sus_data_standardize() |>
sus_data_filter_cid(cid_group = "dengue") |>
sus_data_aggregate(by = "month")
)
sus_rap_targets() — Generating the
_targets.R
The sus_rap_targets() function takes a
climasus4r pipeline and generates a _targets.R
file ready to be run with the targets package.
Function signature
sus_rap_targets(
pipeline,
file_path = "_targets.R",
branching = c("none", "uf", "year", "cross"),
workers = 1L,
include_qc = TRUE,
lang = "pt",
overwrite = FALSE
)Basic usage
sus_rap_targets(
pipeline = pipeline,
file_path = "_targets.R",
branching = "none",
workers = 1L,
include_qc = TRUE,
lang = "pt"
)
#> i Gerando _targets.R para 'Pipeline SINAN' (branching: none)...
#> v Pipeline targets criado: /path/to/_targets.RThe generated _targets.R file contains all the structure
needed for targets to track dependencies and manage the
cache. Here is a simplified excerpt:
# _targets.R -- Generated by climasus4r::sus_rap_targets()
# Pipeline: Pipeline SINAN
# Created : 2026-06-18 10:30:00
library(targets)
library(tarchetypes)
library(climasus4r)
library(dplyr)
options(clustermq.scheduler = "sequential")
list(
tar_target(params_uf, c("CE", "RN", "PB", "PE", "AL")),
tar_target(params_years, 2018:2022),
tar_target(params_system, "SINAN"),
tar_target(params_time_unit, "month"),
tar_target(params_lang, "pt"),
tar_target(pipeline_sinan,
climasus4r::sus_data_import(
uf = params_uf,
year = params_years,
system = params_system,
lang = params_lang
)
),
tar_target(pipeline_sinan_qc,
climasus4r::sus_data_quality_report(pipeline_sinan)
),
NULL
)The overwrite parameter
By default, overwrite = FALSE protects existing files.
If a _targets.R already exists at the given path, the
function issues a warning and stops. Use overwrite = TRUE
to replace it:
# Replace an existing _targets.R
sus_rap_targets(
pipeline = pipeline,
file_path = "_targets.R",
overwrite = TRUE
)
#> ! Arquivo _targets.R existente sera substituido (overwrite = TRUE).
#> v Pipeline targets criado: /path/to/_targets.RThe 4 Branching Strategies
The branching parameter defines how the pipeline is
split into parallel branches. Each strategy has an ideal use
case:
"none"
Single analysis. All states and years processed together. Ideal for national analyses or rapid prototyping.
"uf"
One branch per state (UF). Ideal for inter-state comparisons with independent caching per federative unit.
"year"
One branch per year. Useful for long time series where past years rarely change after collection.
"cross"
Cartesian product of state x year. Maximum parallelism. Requires more workers and disk space.
Branching by state ("uf")
sus_rap_targets(
pipeline = pipeline,
file_path = "_targets_uf.R",
branching = "uf",
workers = 4L
)
#> i Gerando _targets.R para 'Pipeline SINAN' (branching: uf)...
#> i Estrategia: 1 branch por UF (5 UFs detectados)
#> v Pipeline targets criado: /path/to/_targets_uf.RWith branching = "uf", the generated
_targets.R uses targets::tar_map() to create
an independent branch per state. The relevant excerpt of the generated
file looks like this:
# Excerpt of the generated _targets_uf.R
list(
tar_target(params_uf, c("CE", "RN", "PB", "PE", "AL")),
tar_target(params_years, 2018:2022),
tar_map(
values = list(uf = c("CE", "RN", "PB", "PE", "AL")),
tar_target(pipeline_sinan,
climasus4r::sus_data_import(
uf = uf,
year = params_years,
system = "SINAN"
),
pattern = map(params_uf)
)
),
NULL
)Each state has its own cache: if the data for "CE"
changes, only the "CE" branch is re-executed. The others
remain cached.
Cross branching ("cross")
sus_rap_targets(
pipeline = pipeline,
file_path = "_targets_cross.R",
branching = "cross",
workers = 8L
)
#> i Gerando _targets.R para 'Pipeline SINAN' (branching: cross)...
#> i Estrategia: produto cartesiano UF x ano (5 UFs x 5 anos = 25 branches)
#> ! Aviso: 25 branches com workers = 8 pode exigir bastante memoria RAM.
#> v Pipeline targets criado: /path/to/_targets_cross.R
sus_rap_make() — Running the Pipeline
The sus_rap_make() function runs the pipeline generated
with sus_rap_targets() by calling
targets::tar_make() internally, with integration into
climasus4r’s metadata system.
Function signature
sus_rap_make(
rap,
workers = 1L,
reporter = "verbose",
branching = "none",
lang = "pt",
...
)Basic execution
resultado <- sus_rap_make(
rap = rap,
workers = 1L,
reporter = "verbose",
lang = "pt"
)
#> i Executando via targets::tar_make()...
#> * Target params_uf
#> * Target params_years
#> * Target params_system
#> * Target params_time_unit
#> * Target pipeline_sinan [10.3s]
#> * Target pipeline_sinan_qc [0.8s]
#> v Execucao targets concluida.Accessing the results
The object returned by sus_rap_make() is a list with
three components:
# Access results
head(resultado$results) # final pipeline data.frame
resultado$store # path to the cache directory (_targets/)
resultado$rap # original rap_object with updated metadata
# You can also use targets' native API
targets::tar_load(pipeline_sinan)
targets::tar_read("pipeline_sinan_qc")
targets::tar_visnetwork() # visual dependency graphThe power of caching: second run
On the second run of the same pipeline, targets checks
the hash of each target. If nothing changed in the inputs, the target is
marked [skipped] and loaded directly from the cache —
without re-running the code:
# Second run: only what changed is re-executed
resultado2 <- sus_rap_make(rap, workers = 1L)
#> i Executando via targets::tar_make()...
#> * Target params_uf [skipped]
#> * Target params_years [skipped]
#> * Target params_system [skipped]
#> * Target params_time_unit [skipped]
#> * Target pipeline_sinan [skipped] # cache valido!
#> * Target pipeline_sinan_qc [skipped] # cache valido!
#> v Execucao targets concluida.This means that, when only the CID-10 filter is changed, only the
steps starting from sus_data_filter_cid() are re-executed.
The import and encoding steps remain cached.
Running with parallelism
For pipelines with branching = "uf" or
"cross", parallelism is enabled with
workers > 1. climasus4r uses the
future/furrr framework internally:
# Run with 4 parallel workers
resultado_paralelo <- sus_rap_make(
rap = rap,
workers = 4L,
reporter = "verbose",
branching = "uf",
lang = "pt"
)
#> i Executando via targets::tar_make() com 4 workers (future::multisession)...
#> * Target pipeline_sinan_CE [3.1s]
#> * Target pipeline_sinan_RN [2.8s] # executando em paralelo com CE
#> * Target pipeline_sinan_PB [3.4s]
#> * Target pipeline_sinan_PE [3.0s] # executando em paralelo com PB
#> * Target pipeline_sinan_AL [2.5s]
#> v Execucao targets concluida em 7.2s (vs ~14s sequencial).Workflow with targets + renv
For maximum reproducibility, combine targets’s smart
caching with renv’s dependency management. This combination
ensures that both the package environment and the
intermediate results are reproducible:
# 1. Initialize renv and create a snapshot of the dependencies
renv::init()
renv::snapshot()
# 2. Generate _targets.R with the appropriate branching strategy
sus_rap_targets(
pipeline = pipeline,
file_path = "_targets.R",
branching = "uf",
workers = 4L
)
# 3. Run the pipeline (uses the _targets.R generated in the previous step)
sus_rap_make(rap, workers = 4L)
# 4. Check the pipeline status at any time
targets::tar_progress() # status of each target
targets::tar_outdated() # outdated targets
targets::tar_visnetwork() # interactive dependency graphRecommended project structure
A well-organized climasus4r project using
targets and renv follows this directory
structure:
# Recommended structure for a climasus4r + targets project
# meu_projeto_dengue/
# ├── _targets.R # generated by sus_rap_targets()
# ├── _targets/ # targets cache (do not version in git)
# ├── renv/ # renv environment
# ├── renv.lock # dependency snapshot (version this)
# ├── R/
# │ └── funcoes_aux.R # project helper functions
# ├── data/
# │ └── dados_brutos/ # raw data (do not version)
# ├── output/
# │ ├── figuras/
# │ └── tabelas/
# └── relatorio.Rmd # final report that loads from the cacheReferences
Landau WM (2021). The targets R package: a dynamic Make-like function-oriented pipeline toolkit for reproducibility and high-performance computing. Journal of Open Source Software, 6(57), 2959. https://doi.org/10.21105/joss.02959
Marwick B, Boettiger C, Mullen L (2018). Packaging data analytical work reproducibly using R (and friends). The American Statistician, 72(1), 80–88. https://doi.org/10.1080/00031305.2017.1375986
Navigation: Previous: RAP 1 - Export and Run | Next: RAP 3 - Share and Scaffolding
climasus4r · Integrated health-climate-environment analysis in Brazil
Found an issue or have suggestions for this tutorial?
🐛 Report on GitHub