Trial designers often are unsure about some of the inputs to
lago_optimization(), chiefly the outcome goal and the assumed intervention
costs. lago_sensitivity() answers "how much does the recommendation move
if that input is different?" by re-running lago_optimization() across a
sweep of one input and reporting how the recommended intervention, its cost,
and the estimated outcome change. This turns a single point recommendation
into a robustness picture: a stringency curve for the outcome goal, or a
straight line for a uniform cost rescaling.
The confidence set is the slow part of lago_optimization() and is not
needed to see how a recommendation moves, so every run is forced to
include_confidence_set = FALSE for speed. A single run failing does not
abort the sweep: its outputs are recorded as NA and a single warning names
the failed values afterwards.
Arguments
- object
An optional
lagoresult fromlago_optimization(). When supplied, the baseline optimization arguments are taken from the call it carries (so the whole call need not be retyped), and any arguments in...override those stored values. WhenNULL(the default), the baseline arguments come from.... Passing an object that is not alagoresult is an error, as is passing alagoresult from an older version of the package that did not record its call arguments.- ...
The baseline
lago_optimization()arguments (the user's own optimization call). They are forwarded unchanged to every run. Whenobjectis not supplied, these are the baseline arguments and the user typically copies theirlago_optimization(...)call in and simply addsparameterandvalues. Whenobjectis supplied, anything here overrides the arguments stored on the object.include_confidence_setandquietsupplied here are overridden (see Details).- parameter
A single character string naming what to vary. Two modes:
The name of a scalar numeric argument of
lago_optimization()that affects the recommendation (for example"outcome_goal","power_goal", or"icc"). Each run overrides that argument with one element ofvalues. Vector-valued arguments such asintervention_lower_bounds, and confidence-set-only arguments such asconfidence_set_alpha(the confidence set is not computed during a sweep), are rejected.The special string
"cost_multiplier": each run multiplies every coefficient of every vector in the baselinecost_list_of_vectorsby one element ofvalues, sovalues = c(0.8, 1, 1.2)evaluates the costs at 80\...and allvaluesmust be positive.
- values
A non-empty numeric vector, all finite. One run per element.
- quiet
A boolean forwarded to
lago_optimization(). Defaults toTRUEso the sweep is not noisy. Genuine warnings about the data or model fit from each run are still shown.
Value
An object of class "lago_sensitivity", which is a data.frame
with one row per element of values and columns:
- value
The swept value for that run.
One numeric column per intervention component, named by the component, holding its recommended value for that run.
- rec_int_cost
The cost of the recommended intervention.
- est_outcome_goal
The estimated outcome at the recommendation.
- status
"ok"for a successful run, otherwise"error".
The object carries attributes parameter (the swept string),
component_names (the component column names), baseline (the full
lago_optimization() result at the baseline value, i.e. multiplier 1 for
"cost_multiplier" or the value supplied in ... for a named parameter, or
NULL if not present), and, when any run failed, error_messages (the
error text named by the failed values).
Details
Each run builds the modified argument list from ..., forces
include_confidence_set = FALSE, sets quiet = quiet, and calls
lago_optimization() inside tryCatch(). A run that errors contributes a
row of NA outputs with a non-"ok" status instead of stopping the sweep.
See also
Other LAGO functions:
get_confidence_set(),
lago_budget(),
lago_optimization(),
lago_report(),
visualize_cost()
Examples
# \donttest{
# Recommended flow: fit once, then sweep the fitted result. Passing the
# `lago` result reuses its call, so there is no need to retype the
# arguments. Each run is a separate optimization, so this is wrapped in
# \donttest to keep automated checks fast; the confidence set is off
# internally so the sweep still runs quickly.
opt <- lago_optimization(
data = mtcars,
outcome_name = "mpg",
outcome_type = "continuous",
glm_family = "gaussian",
link = "identity",
intervention_components = c("gear", "qsec"),
intervention_lower_bounds = c(0, 0),
intervention_upper_bounds = c(10, 350),
cost_list_of_vectors = list(c(0, 4), c(4, 6)),
outcome_goal = 30,
outcome_goal_intention = "maximize",
include_confidence_set = FALSE,
quiet = TRUE
)
sens <- lago_sensitivity(
opt,
parameter = "outcome_goal",
values = c(30, 35, 40)
)
sens
#>
#> ── LAGO sensitivity analysis ──
#>
#> Varied outcome_goal across 3 runs; 0 failed.
#> value gear qsec rec_int_cost est_outcome_goal status
#> 1 30 10 6.522269 83.13361 30 ok
#> 2 35 10 9.239851 99.43911 35 ok
#> 3 40 10 11.957433 115.74460 40 ok
#> rec_int_cost is 83.13361 at outcome_goal = 30 and 115.7446 at outcome_goal =
#> 40.
plot(sens)
# The same sweep spelled out directly (no fitted object). This is the
# equivalent long form and gives the same result.
sens2 <- lago_sensitivity(
data = mtcars,
outcome_name = "mpg",
outcome_type = "continuous",
glm_family = "gaussian",
link = "identity",
intervention_components = c("gear", "qsec"),
intervention_lower_bounds = c(0, 0),
intervention_upper_bounds = c(10, 350),
cost_list_of_vectors = list(c(0, 4), c(4, 6)),
outcome_goal_intention = "maximize",
parameter = "outcome_goal",
values = c(30, 35, 40)
)
# How sensitive is it to the assumed costs? A uniform rescaling never changes
# which intervention is cheapest, so the recommendation is unchanged and the
# cost scales linearly with the multiplier. `...` overrides on top of the
# fitted object are used here to switch the swept parameter.
cost_sens <- lago_sensitivity(
opt,
parameter = "cost_multiplier",
values = c(0.8, 1, 1.2)
)
cost_sens
#>
#> ── LAGO sensitivity analysis ──
#>
#> Varied cost_multiplier across 3 runs; 0 failed.
#> value gear qsec rec_int_cost est_outcome_goal status
#> 1 0.8 10 6.522269 66.50689 30 ok
#> 2 1.0 10 6.522269 83.13361 30 ok
#> 3 1.2 10 6.522269 99.76034 30 ok
#> rec_int_cost is 66.50689 at cost_multiplier = 0.8 and 99.76034 at
#> cost_multiplier = 1.2.
# }