RaukR 2026 • Data Science With R
Roy Francis
18-Aug-2026
targets concepts and architecturetargets is a pipeline toolkit for R that:
The problem targets solves

_targets.R ← pipeline definition (the only required file)
_targets/ ← cache directory (auto-created)
objects/ ← serialised target outputs
meta/ ← dependency graph metadata
user/ ← user-defined metadata
R/ ← your functions (recommended)
Important
The _targets.R file must be at the project root. It defines all targets using tar_target() inside a list().
Normal code
targets pipeline
This defines a pipeline:
data_raw → data_clean → model → model_summary
tar_manifest() Structure & dependencies# A tibble: 4 × 2
name command
<chr> <chr>
1 data_raw "datasets::mtcars"
2 data_clean "transform(data_raw, am = factor(am, labels = c(\"automatic\", …
3 model "stats::lm(mpg ~ wt + am, data = data_clean)"
4 model_summary "summary(model)"
tar_outdated() targets status[1] "data_clean" "model_summary" "data_raw" "model"
tar_meta() Metadata about targets, status, and dependenciestar_visnetwork() Visualize dependency graph
Opens an interactive graph in the viewer:
| Colour | Meaning |
|---|---|
| Grey | Outdated: will run |
| Green | Up to date: will be skipped |
| Blue | Functions / objects |
| Red | Error |
tar_glimpse() Visualize simpler dependency graphRun specific targets
tar_make(names = "data_clean")
+ data_raw dispatched
✔ data_raw completed [0ms, 1.23 kB]
+ data_clean dispatched
✔ data_clean completed [0ms, 1.26 kB]
✔ ended pipeline [209ms, 2 completed, 0 skipped]

Run all targets
tar_make()
+ model dispatched
✔ model completed [3ms, 3.42 kB]
+ model_summary dispatched
✔ model_summary completed [1ms, 2.33 kB]
✔ ended pipeline [193ms, 2 completed, 2 skipped]

targets tracks three types of dependencies:
| Type | What changes trigger re-run |
|---|---|
| Data | The target’s upstream data changed |
| Command | The R expression in command changed |
| Functions | Any function called in command changed |
Tip
targets hashes the body of every function. Change a function body → downstream targets are automatically invalidated.
Normal pipeline

Place custom functions in R/
And source them at the top of _targets.R:

| Format | Use case |
|---|---|
"rds" |
Default, any R object |
"qs" |
Faster than rds, any R object |
"feather" |
Large data frames |
"file" |
File path returned by command |
Normal pipeline

Create a function to save the plot and return the file path:

tarchetypes provides high-level target archetypes that reduce boilerplate in targets pipelines.
A collection of factory functions that create common target patterns — especially for:

Split one target into independent pieces of work when each piece can run and cache separately.
| Type | Use when | Main tool |
|---|---|---|
Static (tarchetypes) |
The number of tasks is known before the pipeline runs | tar_map() |
| Dynamic | The number of tasks is unknown until the pipeline runs | pattern = map() |
Grouped dynamic (tarchetypes) |
Each data.frame group needs the same work | tar_group_by() + map() |
Dynamic: input decides the branches
New values in input create new branches on the next tar_make().
When you know every case before the pipeline runs.
library(targets)
library(tarchetypes)
species_names <- c(
"setosa",
"versicolor",
"virginica"
)
list(
tar_target(data, datasets::iris),
tar_map(
values = list(
species_name = species_names
),
names = species_name,
tar_target(
data_summary,
dplyr::summarise(
dplyr::filter(data, Species == species_name),
species = dplyr::first(Species),
observations = dplyr::n(),
mean_sepal_length = mean(Sepal.Length)
)
)
)
)
When the number of cases is unknown until the pipeline runs.
library(targets)
list(
tar_target(data, datasets::iris),
tar_target(
species_names,
as.list(sort(unique(data$Species))),
iteration = "list"
),
tar_target(
data_summary,
dplyr::summarise(
dplyr::filter(data, Species == species_names),
species = dplyr::first(Species),
observations = dplyr::n(),
mean_sepal_length = mean(Sepal.Length)
),
pattern = map(species_names),
iteration = "list"
),
tar_target(
data_summary_combined,
dplyr::bind_rows(data_summary)
)
)
Split a data frame into groups and process each group as a branch:
library(targets)
library(tarchetypes)
list(
tar_group_by(
split_data,
datasets::iris,
Species
),
tar_target(
data_summary,
dplyr::summarise(
split_data,
species = dplyr::first(Species),
observations = dplyr::n(),
mean_sepal_length = mean(Sepal.Length)
),
pattern = map(split_data),
iteration = "list"
),
tar_target(
data_summary_combined,
dplyr::bind_rows(data_summary)
)
)
tar_quarto():
tar_read() / tar_load()extra_files for additional files that Quarto does not discover automaticallyformat = "file" targettar_map(): Static Branching - Create named sets of targets from a grid of values:tar_combine(): Aggregating results from branchestar_age(): Time-Based cues - Re-run a target if it is older than a threshold:Tip
Use tar_option_set(packages = ...) instead of library() calls inside each target’s command.
workspace_on_error = TRUE in tar_option_set() automatically saves the workspace when a target errors.
library(targets)
library(tarchetypes)
library(crew)
fn_clean <- function(data) {
dplyr::filter(data,
!is.na(flipper_length_mm), !is.na(body_mass_g)
)
}
fn_summarize <- function(data) {
dplyr::summarise(
data,
penguins = dplyr::n(),
mean_flipper_mm = mean(flipper_length_mm),
mean_body_mass_g = mean(body_mass_g)
)
}
fn_plot <- function(data) {
path <- "output/penguin-flipper-mass.png"
dir.create(dirname(path), showWarnings = FALSE)
plot <- ggplot2::ggplot(
data,
ggplot2::aes(
flipper_length_mm,
body_mass_g,
colour = species
)
) +
ggplot2::geom_point() +
ggplot2::labs(
x = "Flipper length (mm)",
y = "Body mass (g)"
)
ggplot2::ggsave(
path, plot, width = 7, height = 5
)
path
}
tar_option_set(
packages = c("dplyr", "ggplot2", "palmerpenguins"),
format = "rds",
seed = 42,
controller = crew::crew_controller_local(workers = 2)
)
list(
tar_target(data_raw, palmerpenguins::penguins),
tar_target(data_clean, fn_clean(data_raw)),
# Run one summary branch for each species.
tar_group_by(data_grouped, data_clean, species),
tar_target(
species_summary,
fn_summarize(data_grouped),
pattern = map(data_grouped),
iteration = "list"
),
tar_target(
data_combined,
dplyr::bind_rows(species_summary)
),
tar_target(
plot_file,
fn_plot(data_clean),
format = "file"
)
)
R/ to declutter the pipelinetar_option_set(packages = ...) instead of library() calls inside each targettar_option_set(seed = 42)_targets/ to .gitignoretar_visnetwork(targets_only = TRUE) to hide functions and reduce cluttertar_read() only for interactive exploration; avoid in pipeline commandstar_make(callr_function = NULL) to run the pipeline in the main R session for troubleshootingtar_meta(fields = error, complete_only = TRUE)crew package for parallel execution of targetstar_cue(mode = "always") for targets that should always re-run or tar_age() for time-based re-runstar_quarto() or tar_render(). R code in a quarto document can be treated as a pipeline target using tar_tangle()tarchetypes reference