---
title: "Optimizing an intervention with LAGO"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Optimizing an intervention with LAGO}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(LAGOtrials)
```

Learn-As-you-GO (LAGO) trials adapt a multi-component intervention as the trial
proceeds. At each stage the intervention is refined using the data collected so
far, so that the next stage moves toward an intervention that is effective and
affordable. The `LAGOtrials` package fits the outcome model, recommends the
lowest-cost intervention package that is expected to meet an outcome goal (and,
optionally, a power goal), and computes a confidence set for that
recommendation.

This vignette walks through a single optimization on the BetterBirth data that
ships with the package. For the full argument reference see
`?lago_optimization`; for other worked examples see the
[manual tests](https://github.com/correspondMerchant/LAGO-R-Package/tree/main/tests/manual_tests)
folder.

## The data

`BB_data` is a cleaned version of the BetterBirth study, a trial of the World
Health Organization's Safe Childbirth Checklist in Uttar Pradesh, India. The
binary outcome `pp3_oxytocin_mother` records whether oxytocin was administered.
We treat two intervention components as adjustable: `coaching_updt` (number of
coaching visits) and `launch_duration` (days of checklist launch).

```{r}
bb_data <- BB_data
head(bb_data[, c("coaching_updt", "launch_duration", "pp3_oxytocin_mother")])
```

## Recommending an intervention

Suppose we want the least costly intervention that raises the probability of
oxytocin administration to at least `0.85`, for a center with a birth volume of
1.75 (in hundreds). The costs of the two components are `1.7` and `8` per unit,
respectively.

```{r}
result <- lago_optimization(
  data = bb_data,
  outcome_name = "pp3_oxytocin_mother",
  outcome_type = "binary",
  intervention_components = c("coaching_updt", "launch_duration"),
  intervention_lower_bounds = c(1, 1),
  intervention_upper_bounds = c(40, 5),
  center_characteristics = "birth_volume_100",
  center_characteristics_optimization_values = 1.75,
  cost_list_of_vectors = list(c(0, 1700), c(0, 8000)),
  outcome_goal = 0.85,
  outcome_goal_intention = "maximize",
  confidence_set_grid_step_size = c(1, 0.5),
  quiet = TRUE
)
```

The `quiet = TRUE` argument suppresses the progress messages so the vignette
output stays clean; it does not change the result.

The returned object has a `print()` method that shows the full result on the
console: an inputs recap, the fitted outcome-model coefficient table, the
overall intervention-effect test, the recommended intervention with its cost and
the estimated-outcome confidence interval, and the confidence set:

```{r}
result
```

`summary()` renders the same output:

```{r}
summary(result)
```

The recommended intervention and its cost are available directly:

```{r}
result$rec_int
result$rec_int_cost
```

## Visualizing the confidence set

`plot()` shows the 95% confidence set with the recommended intervention
highlighted:

```{r, fig.width = 6, fig.height = 4}
plot(result)
```

## Adding a power goal

For a binary outcome we can also require a minimum power for the next stage. A
power goal needs a `group` column ("treatment" / "control") and the size of the
next stage. If the trial is clustered, the power calculation can additionally
account for within-center correlation through the `icc` argument (with
`power_goal_cluster_id` naming the clustering column); see `?lago_optimization`.
The example below uses a power goal alone.

```{r}
bb_data$group <- ifelse(bb_data$pre_post == 0, "control", "treatment")

power_result <- lago_optimization(
  data = bb_data,
  outcome_name = "pp3_oxytocin_mother",
  outcome_type = "binary",
  intervention_components = c("coaching_updt", "launch_duration"),
  intervention_lower_bounds = c(1, 1),
  intervention_upper_bounds = c(40, 5),
  center_characteristics = "birth_volume_100",
  center_characteristics_optimization_values = 1.75,
  cost_list_of_vectors = list(c(0, 1700), c(0, 8000)),
  power_goal = 0.8,
  num_centers_in_next_stage = 10,
  patients_per_center_in_next_stage = 30,
  include_confidence_set = FALSE,
  quiet = TRUE
)

power_result$est_outcome_goal
```

When both an outcome goal and a power goal are supplied, the optimization
targets the higher of the two: the outcome goal itself, or the outcome level
implied by the power goal.

## How sensitive is the recommendation?

The recommendation depends on inputs you may be unsure about, above all the
outcome goal and the assumed costs. `lago_sensitivity()` re-runs the
optimization across a sweep of one input and reports how the recommendation, its
cost, and the estimated outcome move. The easiest way is to hand it the fitted
`result` from above: it reuses that call, so you only add `parameter` (what to
vary) and `values` (the sweep).

Here we ask how the recommended cost changes as the target probability tightens
from 0.75 to 0.90. The confidence set is not needed for this, so
`lago_sensitivity()` skips it and the sweep is fast.

```{r}
sens <- lago_sensitivity(
  result,
  parameter = "outcome_goal",
  values = c(0.75, 0.80, 0.85, 0.90)
)

sens
```

The result is a tidy data frame with one row per swept value: the value, the
recommended value of each component, the recommended cost, the estimated
outcome, and a `status` column (a run that fails is recorded as `NA` rather than
stopping the sweep). `plot()` draws the recommended cost as a function of the
swept value:

```{r, fig.width = 6, fig.height = 4}
plot(sens)
```

To vary the costs instead, use `parameter = "cost_multiplier"` with, say,
`values = c(0.8, 1, 1.2)` to scale every cost by plus or minus 20%.
