The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Fixed two unclear refusals for fixed center and time effects. An
all NA center column was refused with “values
in center_weights_for_outcome_goal must sum up to 1”, or with a message
about the length of center_weights_for_outcome_goal when
the weights were given. It is now refused with the same kind of message
an all NA period column gets. A center or
period whose rows all have zero weight counted as usable, so when no
other center or period was left the fit failed with a rank deficiency
message that blamed collinear predictors. Such a level no longer counts,
and the message names the center or period that still has a positively
weighted row, if there is one.
get_confidence_set() now refuses a fitted model with
a factor, character or logical predictor that is not treatment coded
with its first level as the reference and each coefficient named after
its level. Examples are a model fitted with contr.sum,
contr.SAS, a global options(contrasts = ...)
that sets another coding, the default coding of an ordered factor, or a
treatment matrix such as contr.treatment(3) whose columns
are not named after the levels. The function reads every such predictor
that way. For a binary outcome it returned a wrong interval and
confidence set without any error. A treatment matrix whose columns are
not named after the levels gave a wrong result only for the period,
whose dummy is found by its level name, and is now refused for every
column so that one rule applies. For a continuous outcome it usually
failed with a message about unmatched columns, but it could also return
a wrong interval without any error, for example for a factor with levels
0 and 1. The new message names each such column and shows how to refit
the model. Models fitted by lago_optimization() already use
this coding, so its results are unchanged. Results from direct calls
with such a model should be recomputed after refitting it.
Fixed a data column named weights replacing the
weights of the outcome model. glm() looked up its
weights argument in the data first, so such a column
replaced the weights argument of
lago_optimization(), replaced
center_sample_size for center level data, and weighted the
fit even when no weights were given. A row with a missing value in that
column was also dropped from the fit. The outcome model now always uses
the weights argument, or center_sample_size
for center level data, and a column named weights is used
only where it is named, such as an additional covariate. This also
applies to lago_sensitivity() and
lago_budget(). Results from data with a
weights column should be recomputed.
Continuous confidence covariance now uses the actual fitted model’s prior weights. Identity covariance uses weighted bread and residual scores, with estimated residual scale divided by the positive weight row count minus the design column count when no clusters are present. Logit covariance retains the existing Gauss Newton bread and HC0 or CR0 sandwich, now with weighted scores. Both clustering dimensions and their intersection use the same fitted weights. Weights are relative observation weights, so a common positive rescaling leaves covariance unchanged for a fixed fit. Zero weight rows contribute nothing, malformed fitted weights are refused, and unclustered identity covariance requires positive residual degrees of freedom. Binary covariance and existing finite unit weight results are unchanged. This extends the existing continuous formulas, not a frequency weight, survey design or general GLM covariance. The existing continuous quasibinomial family variance mismatch is not changed. Results from continuous fits with nonconstant weights should be recomputed.
Fixed recommendations and confidence output that depended on global contrast options or polynomial coding of ordered covariates. Every categorical predictor in the outcome model now uses treatment contrasts, including factor, ordered factor, character and logical covariates and center characteristics. This overrides explicit contrast attributes without changing input data or global options. Additional categorical covariates are held at their reference level. For a categorical center characteristic with two levels, optimization values 0 and 1 select the reference and other level. Numeric predictors and the existing center and period checks are unchanged. Results from affected runs should be recomputed.
Fixed wrong results when the center or
period column was not coded with one effect per level.
glm() fits an ordered factor with polynomial contrasts, and
a global options(contrasts = ...) such as
contr.sum changes the coding of every factor, but the
package read the resulting coefficients as one effect per center or
period. With fixed center effects, a binary outcome or any run without
the confidence set returned a wrong recommendation and estimate without
any error, and a continuous outcome failed when it computed the
confidence set. With fixed time effects an ordered period was refused
except at its first level, and under a global coding such as
contr.sum or contr.helmert whether a period
was refused depended on its label. A period that was not refused could
give a wrong result in the same way. The outcome model now always fits
center and period with treatment contrasts,
and an ordered center or period is converted
to an unordered factor with the same levels, with a message. Results
from such runs should be recomputed.
Fixed center or time effects with fewer than two centers (or
periods) are now refused with a message that says whether the data has
no observed period, only one center (or period), or only one with a row
the outcome model can use, and names that level, instead of failing
inside glm() with “contrasts can be applied only to factors
with 2 or more levels”. A fit with center or time effects where no row
is usable at all is refused with a message that says so.
Fixed results that used rows the outcome model never fitted.
glm() drops a row with a missing value in any model
variable, but the confidence set was computed over every row, and the
center weights covered every center in the data. With a continuous
outcome and missing values the confidence set came back empty or wrong,
with or without fixed center or time effects, and in some cases the call
failed (for example with fixed center effects and a missing covariate,
or a missing period with fixed time effects), so such results should be
recomputed. A center whose every row has a missing model variable still
got a weight: lago_optimization() failed when it computed
the confidence set, and otherwise (without the confidence set, after
shrinking, and in lago_sensitivity() and
lago_budget()) it returned results with mismatched center
weights, silently or with at most R’s generic “longer object length”
warning (none when the number of centers is a multiple of the number
fitted), so every run with such a center should be recomputed. The
confidence set now uses the rows the model was fitted on, and the center
weights now cover only the centers it fitted. A center the model could
not fit is left out of the default weights with a warning that names it
(the other centers are still sized by all of their rows, and the
shrinking target and default grid steps still use every row, since the
stage-1 intervention was delivered either way), and naming it in
center_effects_optimization_values, or giving it a non-zero
weight in center_weights_for_outcome_goal, is refused with
a message that names it. A factor center column with unused
levels no longer shifts the default weights onto the wrong centers, and
an explicit NA center level (as from addNA())
is kept as a center when another center is left out (a continuous
outcome’s confidence set still cannot use an explicit NA
level that a fitted row has in the center or period column, or as a
non-reference level of any other factor column, and now says so instead
of reporting a missing cluster id or returning an empty set), and a row
with a missing center no longer counts as a facility when checking
center_weights_for_outcome_goal. For center level data, a
center with no center_sample_size on any row is refused
with a message that names it when the default weights are computed, and
a center whose size is missing on only some rows is sized by its first
observed value.
Fixed lago_optimization() failing for a continuous
outcome when the data is a tibble, such as the bundled
BB_data. With the identity link it failed with “undefined
columns selected” when fixed center or time effects were included, and
with the logit link it failed with “Not compatible with requested type”
with or without them.
The in-browser playground now supports fixed center effects: tick
“Fixed center effects” to adjust the outcome model for each center,
matching lago_optimization()’s
include_center_effects, and choose whether to optimize for
the size-weighted average center or for one named center
(center_effects_optimization_values). The center column
comes from the data’s own center column when it has one,
used as is, otherwise from a column you pick (site_name for
BB_data), and the shown R code includes the line that
builds it on a copy of the data. Fixed center effects replace center
characteristics, which the package cannot fit together, and the center
column is not offered as a component or an additional covariate. The
sensitivity sweep, budget search and Share link carry the setting. A
center with no row where all the model columns are observed is left out
of the fit, and the page asks for another center if you chose it as the
one to optimize for.
The documentation of
center_effects_optimization_values now says it is a single
center name (a character string), which is what
lago_optimization() has always required, rather than a
numeric vector.
Fixed an outcome goal or a power goal failing when the outcome
column has missing values. The check of the outcome goal’s direction
compared it against the outcome mean without removing missing values, so
any missing outcome stopped lago_optimization() with
“missing value where TRUE/FALSE needed”. The power calculation counted a
row with a missing outcome toward its arm’s size but made the arm’s sum
missing, so the default unconditional approach failed the same way and
the conditional approach silently returned a power-implied outcome of 0,
which dropped the power goal. Both now use only rows with an observed
outcome, as the final treatment-versus-control test does, and a power
goal now needs a group column with both arms present and an
observed outcome in each.
Fixed the in-browser playground misreading a column named like a
built-in JavaScript property (for example constructor or
toString). Ticked as an intervention component, it made the
generated R code, Run, the sensitivity sweep and the budget search fail,
and its bounds and unit cost came up collapsed or blank instead of the
column’s defaults. As a center characteristic, its held-at value came up
blank and was left out of the call.
The in-browser playground now supports a power goal (binary
outcomes): tick “Power goal” to plan for the next stage’s statistical
power alongside, or instead of, the outcome goal, matching
lago_optimization()’s power_goal,
num_centers_in_next_stage,
patients_per_center_in_next_stage,
power_goal_approach, icc and
power_goal_cluster_id. The treatment arm comes from the
data’s own group column when it has one (used as is, so it
must hold only “treatment” and “control” with both present), otherwise
from a complete 0/1 column you pick (pre_post for
BB_data, as in the package tests), and the shown R code
includes the lines that build it on a copy of the data. Direction must
be Maximize, and Run stays disabled with a hint until the power settings
are complete. The ICC cluster column list offers only columns with at
least two non-missing centers with an observed outcome in each arm,
checked when an ICC is entered. The sensitivity sweep can vary the power
goal, and the budget search and Share link carry the settings. On
BB_data the stage-1 data already powers the comparison, so
the power goal alone recommends no intervention, and the printed result
reports the power-implied outcome.
The in-browser playground now has an optional “Additional
covariates” section: tick any columns (numeric or not, for example a
site or arm label) to adjust the outcome model for them, matching
lago_optimization()’s additional_covariates. A
column can play only one role at a time (intervention component, center
characteristic, or additional covariate). The chosen covariates ride
along in the Share link.
The in-browser playground now supports fixed time effects: when
the loaded data has a period column (so, an uploaded CSV,
since no bundled dataset has one) a “Fixed time effects” checkbox
appears with a period value to optimize at, matching
lago_optimization()’s include_time_effects and
time_effect_optimization_value. (Time effects are not
carried in the Share link, which is offered only for bundled
datasets.)
The in-browser playground now has an optional “Interaction terms”
section: with two or more intervention components ticked, tick a pair to
model their product (for example
coaching_updt × launch_duration). It sets
include_interaction_terms = TRUE and
main_components, appends the a:b term to
intervention_components, and prepends the line that creates
the interaction’s product column so the shown R code stays
copy-pasteable. Bounds, costs and the confidence set stay per main
component, and the sensitivity sweep, budget search and Share link
inherit the interactions.
The in-browser playground’s “Share link” now carries the whole page, not just the core optimization: the center characteristics and their held-at values, the interaction terms, the additional covariates, a budget you have entered, and the sensitivity sweep’s input, range and step count all round-trip through the URL, so an opened link reproduces the full setup. Older or hand-trimmed links that omit these simply keep the page’s own defaults for those controls.
The in-browser playground now has an optional “Center
characteristics” section: tick numeric columns (for example a center’s
birth volume) and set the value each is held at, and the recommendation
is computed for a center with those characteristics, matching
lago_optimization()’s center_characteristics
and center_characteristics_optimization_values. The
sensitivity sweep and budget search inherit the same setting. A column
can be an intervention component or a center characteristic but not
both.
The in-browser playground now has a “Budget” section that
surfaces lago_budget(): enter a cost budget and it finds
the best outcome reachable within it and the intervention that reaches
it (the reverse of setting an outcome goal). It reports the
recommendation, its cost and estimated outcome (or that no intervention
fits), notes when the budget does not bind, and draws the cost/outcome
frontier as an interactive D3 chart with the budget line and the chosen
point marked. The budget field auto-fills a sensible default from the
current costs and bounds until it is edited.
Added lago_budget(), which answers the reverse of
the usual LAGO question: given a fixed cost budget, what is the best
outcome reachable, and with which intervention? It searches the outcome
goal along the least-cost frontier lago_optimization()
traces out and returns the most ambitious reachable goal whose
recommended cost fits the budget (the lowest reachable outcome within
budget for outcome_goal_intention = "minimize"), with
print() and plot() methods and a
frontier of the cost-vs-outcome points searched. Like
lago_sensitivity(), it reuses a fitted lago
result’s call or takes the arguments directly, and it never computes the
confidence set. It reports whether the budget is feasible and whether it
binds.
Fixed the in-browser playground’s default configuration not
producing a result. It prefilled the first binary column as the outcome,
which for BB_data is the pre_post pre/post
period flag: perfectly separable from the coaching components, so the
outcome model never converged and Run (and the sensitivity sweep)
errored out of the box. Each bundled dataset now starts from a preset
that fits (BB_data uses the
pp3_oxytocin_mother outcome with the
coaching_updt and launch_duration components;
mtcars uses mpg with gear and
qsec), and switching datasets or pressing Reset lands on
that dataset’s runnable preset. Uploaded CSVs keep the generic
prefill.
The in-browser playground now has a “Sensitivity sweep” section
that re-runs the recommendation across a range of one input, using
lago_sensitivity(). Pick the input to vary (the outcome
goal or a cost multiplier), a from/to range and a number of steps, and
it draws how the recommended cost moves as an interactive D3 line (with
each run’s per-component recommendation, estimated outcome and status in
a table beneath). The confidence set is skipped during the sweep for
speed, and a failed run is shown as a gap rather than aborting the
sweep.
The in-browser playground now has a “Share link” button that encodes the whole current setup (bundled dataset, outcome column and type, intervention components, their bounds and costs, the goal and direction) into the page URL and copies it to the clipboard. Opening that link restores the configuration on load, ready to run. Costs are encoded as per-component coefficient vectors, so a curve shaped in the cost designer is preserved along with plain unit costs. Sharing is offered only for the bundled datasets, since an uploaded CSV cannot be carried in a URL.
The in-browser playground and the cost designer now round-trip. A
“Shape costs in the designer” button opens visualize_cost()
in the browser pre-loaded with the intervention components, bounds and
unit costs configured in the playground (the designer reads this from
its page URL query and falls back to its built-in example when the query
is absent or malformed; a plain visualize_cost(...) call is
unchanged). In the designer, a “Use these costs in the playground”
button sends the shaped cost functions back to the playground tab, which
then uses them as cost_list_of_vectors for the optimization
(shown in the reproducible R code) instead of the linear unit cost;
adjusting a component’s unit cost reverts it.
visualize_cost() now has a “Cost function form”
toggle that switches all components between the linear and cubic cost
functions live, instead of the form being fixed for the whole session by
default_cost_fxn_type. Switching resets each component to
that form’s initial coefficients and shows the right number of
coefficient sliders (2 for linear, 5 for the cubic’s degree-4 total
cost). The cubic form opens on a visibly curved (but still valid) demo
cost rather than the near-linear one cost_fxn_calculator()
returns for typical unit costs, so the toggle clearly shows a cubic.
This also gives the in-browser cost designer a cubic option.
The total cost curve in visualize_cost() can now be
reshaped by dragging: each curve carries a draggable handle at several
points along it, and dragging one refits the cost function through the
new set of points (and updates the sliders), instead of the single
right-endpoint handle that only rescaled the whole curve.
The fitted outcome model’s Call:, shown in the
“Outcome model fit” section of print() and
summary(), now displays the actual model formula instead of
the literal word formula. This also makes the console
output identical across R versions: a change in recent R to how the
unrecorded formula deparses had otherwise made the output (and its
snapshot tests) version dependent.
Added a live in-browser demo to the documentation site
(live-demo.html) that runs the real package client-side
with webR (R compiled to WebAssembly), so anyone can try
lago_optimization() with no installation, plus an
interactive playground (playground.html) where you pick a
bundled dataset or upload a CSV, configure the model with sliders and
toggles, and see the recommendation drawn with the package’s own D3
charts alongside a copy-pasteable R snippet. A GitHub Actions workflow
builds the package to WebAssembly with the rwasm toolchain and publishes
it as a small CRAN-like repository alongside the site.
Added a browser version of visualize_cost(): the
same Shiny cost-function designer now runs client-side on the
documentation site (/visualize-cost/), exported with
shinylive, so you can shape each component’s cost curve and copy the
coefficient list with no install. visualize_cost() was
refactored to build its app object separately from launching it, so the
local and in-browser versions share one implementation.
lago_report() now renders an interactive HTML
dashboard: the confidence set is a hover-enabled D3 plot (a scatter for
two components, a strip for one) with the recommended intervention
highlighted, and each intervention component gets interactive total-cost
and marginal-cost curves. The report stays a single self-contained
offline file (D3 is inlined, no CDN or server) and its API is unchanged;
rendering now also uses jsonlite (a new Suggests).
Added an MCP (Model Context Protocol) server to the Python
package (python -m lago.mcp_server) that exposes
optimize and sensitivity as tools any
MCP-aware AI agent can call, plus a sensitivity() function
in the Python wrapper.
Added lago_sensitivity(), which re-runs an
optimization across a sweep of one input (an outcome or power goal, or a
"cost_multiplier" that scales all costs) and reports how
the recommended intervention, its cost, and the estimated outcome move,
with print() and plot() methods.
The package is now installed and loaded as
LAGOtrials (call library(LAGOtrials)); the
previous LAGO identifier clashed with an archived CRAN
package. Function names, the lago result class, and the
LAGO method name are unchanged.
visualize_cost() now stores the returned cost list
in the lago_cost_list option instead of assigning it to the
global environment; retrieve it with
getOption("lago_cost_list").
Added tests for the interaction-terms optimization path and the
outcome-model fit warnings, and excluded the interactive
visualize_cost() app from the coverage figure so it
reflects the testable R code.
Added a CITATION.cff so the repository can be cited,
plus contributing guidelines, a code of conduct and issue/pull-request
templates. (#86)
Added test-coverage reporting, cross-platform (macOS, Windows, Linux) continuous integration, project-status and coverage badges, and a social-preview card. (#83, #84, #85)
Added a Python wrapper (in python/, importable as
lago) that calls LAGOtrials through rpy2.
(#81)
visualize_cost() now draws its cost curves
client-side with D3, with hover read-outs, a draggable curve endpoint,
and invalid-state highlighting. (#80)
The clustered variance estimator for logit outcomes is now
computed by a compiled Rcpp kernel, so Rcpp is a new
dependency. (#79)
lago_optimization() now refuses an additional
covariate whose column is entirely NA, naming it.
(#77)
A rank-deficient outcome model is now refused up front with an error naming the aliased terms. (#74, #76)
Added a warning when glm() drops an additional
covariate as collinear. (#76)
Fixed confidence-interval bounds for a binary logit outcome being
reported outside [0, 1]. (#75)
Fixed the estimated outcome being scaled by center weights that did not sum to 1. (#72, #75)
Added a warning when a binary outcome’s estimated outcome is
reported outside [0, 1]. (#75)
Added a warning when a numeric additional covariate observed away from 0 is held at 0 for the confidence set. (#75)
Fixed the confidence interval and set being computed on the logit scale for an identity-link binomial model. (#74)
center_weights_for_outcome_goal must now be numeric,
finite and non-negative, checked at both entry points. (#73,
#74)
Fixed the numerical optimizer failing with an opaque error when every restart failed, so it now gives an actionable message. (#73)
Fixed a factor covariate named like “center” or “period” being
miscounted as a fixed effect when get_confidence_set() is
called directly. (#73)
Fixed outcome_goal_intention = "minimize" ignoring
the outcome goal on a logit link. (#70)
Fixed the recommended intervention sometimes falling outside the intervention bounds. (#70)
Fixed the numerical optimisation returning its most expensive candidate solution instead of the cheapest. (#70)
Fixed the estimated outcome being wrong when more than one center characteristic was supplied. (#70)
link = "probit" and link = "log" are no
longer accepted, since only logit and identity
were ever implemented. (#70)
Fixed $est_outcome_ci sometimes reporting the wrong
interval instead of the one at the recommended intervention.
(#68)
Fixed the confidence set occasionally dropping one of its qualifying interventions. (#68)
Fixed confidence_set_size_percentage understating
the size of the confidence set. (#68)
A confidence set containing exactly one grid intervention is no longer discarded as empty. (#68)
Fixed confidence-interval bounds being attached to the wrong interventions under two-way clustering. (#68)
get_confidence_set() now returns
rec_int_ci, the interval at the recommended intervention
(its return shape changed for direct callers). (#68)
The confidence set, its size, and the estimated-outcome interval can differ from earlier releases wherever the previous values were wrong. (#68)
Fixed get_confidence_set() pairing the prediction
matrix with the model coefficients by position instead of by name.
(#68)
Fixed the estimated outcome being reported as 0 for the reference period when fixed time effects were included. (#68)
Fixed the estimated-outcome interval being computed at the wrong time period. (#68)
Fixed an additional covariate or center characteristic named like “center” being miscounted as a fixed center effect. (#68)
Fixed a factor or character additional covariate or center characteristic being paired with the wrong coefficient or erroring. (#68)
Fixed the confidence set changing when the rows of
data were reordered. (#68)
Fixed passing more than one center characteristic to the confidence set failing or duplicating a column. (#68)
Added runnable @examples to every exported function
that lacked them. (#67)
Restyled the print() and summary()
console output with boxed cli sections. (#65)
The fitted outcome model ($model) and the
estimated-outcome interval ($est_outcome_ci) are now
returned on the result. (#65)
Added lago_report(), which renders a self-contained
HTML report of a result. (#64)
lago_optimization() now returns a
"lago" object with print(),
summary(), and plot() methods. (#61)
Added an “Optimizing an intervention with LAGO” vignette. (#61)
Added a hex logo and refreshed the README header. (#56, #61)
Added a quiet argument to
lago_optimization() that skips progress messages.
(#60)
visualize_cost() gained a copy-to-clipboard button,
a numeric cost summary, and returns the cost list on close.
(#59)
Expanded the reference documentation for the bundled datasets. (#58)
Added a GPL-3 LICENSE file. (#56)
Fixed a crash when a single intervention component was used. (#54)
Added a pkgdown documentation site published to GitHub Pages. (#53)
The overall intervention-effect test result is now returned in the result object. (#49)
Added an automated test suite (testthat) and continuous-integration checks. (#45)
lago_optimization() now accepts a standalone power
goal, an outcome goal, or both together. (#40)
Added non-fatal outcome-model fit diagnostics. (#36)
visualize_cost() sliders now support per-component
default and custom ranges. (#34)
Supplying optimization_grid_search_step_size now
switches the optimization method to grid search automatically.
(#32)
Added an icc argument so the power goal can account
for within-center clustering. (#29)
outcome_goal_intention. Under
outcome_goal_intention = "minimize" it can therefore
contain interventions whose estimated outcome is above the goal, and
which cost more than the recommendation, because their interval still
reaches the goal from above. Read the confidence set as the
interventions the data cannot distinguish from the goal, not as the
interventions that meet it. The estimated outcome and its interval,
reported as est_outcome_goal and
est_outcome_ci, are computed at the recommended
intervention and are direction independent, so they are unaffected.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.