Add feature-level relative targets to a planning problem.
These targets are stored in the problem object and later translated into linear constraints when the optimization model is built. Relative targets are supplied as proportions in \([0,1]\) and are converted internally into absolute thresholds using the current total amount of each feature in the landscape.
Each call appends one or more target definitions to the problem. This makes it possible to combine multiple target rules, including targets associated with different action subsets.
Arguments
- x
A
Problemobject.- targets
Target specification as proportions in \([0,1]\). It may be a scalar, vector, named vector, or
data.frame. See Details.- features
Optional feature specification indicating which features the supplied target values refer to when
targetsdoes not identify features explicitly. IfNULL, all features are targeted.- actions
Optional character vector indicating which actions count toward target achievement. Entries may match action ids,
action_setlabels, or both. IfNULL, all actions count.- label
Optional character string stored with the targets for reporting and bookkeeping.
Details
Use this function when target requirements are naturally expressed as proportions of current baseline feature totals rather than in original feature units.
Let \(\mathcal{F}\) denote the set of features. For each targeted feature
\(f \in \mathcal{F}\), let \(B_f\) denote the current baseline total
amount of that feature in the landscape, as computed by
.pa_feature_totals().
If the user supplies a relative target \(r_f \in [0,1]\), then this function converts it to an absolute threshold: $$ T_f = r_f \times B_f. $$
The absolute threshold \(T_f\) is stored in target_value, while:
the original user-supplied proportion \(r_f\) is stored in
target_raw,the baseline total \(B_f\) is stored in
basis_total.
When the optimization model is built, the resulting target is interpreted as: $$ \sum_{(i,a) \in \mathcal{D}_f^{\star}} c_{iaf} x_{ia} \ge T_f, $$ where:
\(i \in \mathcal{I}\) indexes planning units,
\(a \in \mathcal{A}\) indexes actions,
\(x_{ia}\) indicates whether action \(a\) is selected in planning unit \(i\),
\(c_{iaf}\) is the contribution of that action to feature \(f\),
\(\mathcal{D}_f^{\star}\) is the subset of planning unit–action pairs allowed to count toward the target for feature \(f\).
The actions argument restricts which actions may contribute toward
target achievement, but it does not affect the baseline amount \(B_f\) used
to compute the threshold. In other words, relative targets are always scaled
against the current full landscape baseline.
Therefore, actions changes who may satisfy the target, but not how the
threshold itself is scaled.
The targets argument is parsed by .pa_parse_targets() and may be
supplied in several equivalent forms, including:
a single numeric value recycled to all selected features,
a numeric vector aligned to
features,a named numeric vector where names identify features,
a
data.framewithfeatureandtargetcolumns.
If targets does not explicitly identify features:
if
features = NULL, the target is applied to all features,if
featuresis supplied, the target values are interpreted with respect to that feature set.
Relative targets must lie in \([0,1]\).
Repeated calls append new target rules rather than replacing previous ones. This allows cumulative target modelling, including multiple rules on the same feature with different contributing action subsets.
Examples
pu_tbl <- data.frame(
id = 1:4,
cost = c(1, 2, 3, 4)
)
feat_tbl <- data.frame(
id = 1:2,
name = c("feature_1", "feature_2")
)
dist_feat_tbl <- data.frame(
pu = c(1, 1, 2, 3, 4),
feature = c(1, 2, 2, 1, 2),
amount = c(5, 2, 3, 4, 1)
)
p <- create_problem(
pu = pu_tbl,
features = feat_tbl,
dist_features = dist_feat_tbl,
cost = "cost"
) |>
add_actions(data.frame(id = "conservation", name = "conservation"), cost = 0)
# Require 30% of the baseline total for all features
p1 <- add_constraint_targets_relative(p, 0.3)
p1$data$targets
#> feature type sense target_unit target_raw basis_total target_value
#> 1 1 actions ge relative_baseline 0.3 9 2.7
#> 2 2 actions ge relative_baseline 0.3 6 1.8
#> actions label created_at feature_name
#> 1 <NA> <NA> 2026-04-23 21:00:04.306099 feature_1
#> 2 <NA> <NA> 2026-04-23 21:00:04.306099 feature_2
# Require 20% for one selected feature
p2 <- add_constraint_targets_relative(
p,
0.2,
features = 1
)
p2$data$targets
#> feature type sense target_unit target_raw basis_total target_value
#> 1 1 actions ge relative_baseline 0.2 9 1.8
#> actions label created_at feature_name
#> 1 <NA> <NA> 2026-04-23 21:00:04.3096 feature_1
# Restrict which actions count toward target achievement
p3 <- add_constraint_targets_relative(
p,
0.2,
actions = "conservation"
)
p3$data$targets
#> feature type sense target_unit target_raw basis_total target_value
#> 1 1 actions ge relative_baseline 0.2 9 1.8
#> 2 2 actions ge relative_baseline 0.2 6 1.2
#> actions label created_at feature_name
#> 1 conservation <NA> 2026-04-23 21:00:04.312923 feature_1
#> 2 conservation <NA> 2026-04-23 21:00:04.312923 feature_2
