From 3b241d85078a14423c43a79183ec1d2f37315795 Mon Sep 17 00:00:00 2001 From: Ante Bing Date: Mon, 10 Aug 2026 19:27:25 +0000 Subject: [PATCH 1/3] Document PRs #72-#77 in NEWS The NEWS 1.0.12 section was last updated at #70. Adds bullets for the user-facing changes merged since, all against the unreleased 1.0.12 dev version (only v1.0.11 is tagged): - identity-link confidence interval computed on the wrong (logit) scale (#74) - logit-link confidence bounds reported outside [0, 1] (#75) - numerical optimizer failing with "argument is of length zero" when every restart of the max-outcome search failed (#73) - rank-deficient outcome model now refused up front, naming the aliased terms, on both optimizer paths (#74, #76) - factor/logical/ordered covariate named "center"/"period" miscounted as a fixed effect on the get_confidence_set() direct-call fallback path (#73) - center weights validated (numeric, finite, non-negative) at both entry points, including the exported get_confidence_set() (#73, #74) - center weights not summing to 1: renormalised in lago_optimization(), refused in the exported get_confidence_set() (#72, #75) - an all-NA additional covariate refused with a clear error (#77) - warnings for a collinear dropped covariate (#76), a binary estimate reported outside [0, 1] (#75), and a covariate held at 0 off its support (#75) #71 is test-only and gets no bullet. Every bullet was verified against the current source. --- NEWS.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/NEWS.md b/NEWS.md index f5eced4..df59ce9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -145,6 +145,94 @@ * Fixed passing more than one center characteristic, which either failed or silently added a single recycled column of values to the confidence set instead of one column per characteristic. +* Fixed the estimated-outcome confidence interval and confidence set being + computed on the logit scale for a binomial outcome model fitted with + `link = "identity"`. The interval branch applied `expit()` and the logit + delta-method factor from the outcome type alone, ignoring the link, so an + identity-link binomial fit was reported on the wrong scale, with bounds that + could exclude the point estimate and wrongly discard or populate the + confidence set. The bounds are now built on the link the model was fitted on. + Binary logit results are unchanged. (#74) +* Fixed the confidence interval bounds for a binary outcome on the logit link + being reported outside `[0, 1]`. The point estimate is `expit()` of the + linear predictor and is a probability by construction, but the delta-method + bounds are symmetric on the probability scale and could fall below 0 or above + 1, so a set reported a lower bound of -0.106 or an upper bound of 1.049 for a + probability. The bounds in `rec_int_ci` and in the confidence set are now + confined to `[0, 1]`, while confidence-set membership is still decided from + the unconfined interval, so an outcome goal of exactly 1 does not drop a + qualifying intervention. (#75) +* Fixed the numerical optimizer failing with the base-R error "argument is of + length zero" when every restart of its maximum-achievable-outcome search + failed. Only the cost search guarded against this, so an all-failed outcome + search reached `which.max()` over all-`NA` results and died before the + package's own message advising the `grid_search` method could appear. Both + searches now raise that actionable message when no restart succeeds. (#73) +* Fixed a rank-deficient outcome model being detected only after a full search + over every intervention. When `glm()` returns `NA` for a coefficient the + optimization reads (the intercept, an intervention component or interaction + term, a fixed center or time effect, or a center characteristic), the fit is + now refused up front with an error naming the aliased terms, before any + intervention is tried. Where such a fit is still reached, both the numerical + and the grid-search paths raise that same error, instead of the numerical one + advising `grid_search`, which fails on the same fit, and the grid one failing + with "missing value where TRUE/FALSE needed". (#74, #76) +* Fixed a factor, logical or ordered additional covariate or center + characteristic whose name begins with "center" or "period" still being + counted as a fixed center or time effect on the path a model passed directly + to `get_confidence_set()` can take, where the fitted model's + term-to-coefficient mapping is unavailable. The names held back from the + fallback name search were column names, but a contrast-coded column's + coefficient is named after the level, so `center_grp` never held back + `center_grpb`, which was then taken for a center dummy and recycled the center + weights into a silently wrong outcome. The held-back names now come from the + coding the model recorded, and a covariate named exactly "center" or + "period", whose dummies cannot be told from the genuine fixed-effect dummies, + raises an error reporting the collision. (#73) +* `center_weights_for_outcome_goal` must now be numeric, finite and + non-negative at both entry points. Only their type, length and sum were + checked before, so weights of -10 and 11 summed to 1 and were accepted, + reporting an outcome of 10.95 for a binary outcome, and a missing weight + surfaced as an opaque "missing value where TRUE/FALSE needed" error. A weight + of exactly 0, which excludes that center from the average, is still allowed. + The exported `get_confidence_set()`, which does not pass through + `validate_inputs()`, previously ran none of these checks and could report a + confidence bound above 1 for a binary outcome. (#73, #74) +* Fixed the estimated outcome being scaled by center weights that did not sum + to 1. Weights whose sum was within a thousandth of 1 passed validation and + were multiplied into the per-center outcomes as supplied, so a set summing to + 0.999 scaled every reported outcome, including the goal comparison the + recommendation is chosen against. `lago_optimization()` now renormalises the + weights it accepts to sum to 1, so the estimated outcome and the + recommendation shift for accepted weights that did not already sum to exactly + 1, and are unchanged for weights that did. The exported `get_confidence_set()` + instead refuses weights that do not sum to 1, since it is handed the weights + an optimization ran with and renormalising them would move the interval away + from the value it was computed at. (#72, #75) +* `lago_optimization()` now refuses an additional covariate whose column is + entirely `NA`, in `validate_inputs()`, with an error naming the offending + covariate(s). Such a column made `glm()`'s internal `na.omit` drop every row, + so the fit died with an opaque "nonempty numeric vector" error deep in model + fitting that never named the covariate. The check catches all-`NA` numeric, + factor and character columns, while a partially or fully observed covariate is + untouched. (#77) +* Added a warning when an additional covariate is dropped by `glm()` as + collinear. Its coefficient is `NA` but the optimization never reads it, so the + run no longer stops or drops it silently: it warns naming the covariate and + continues, returning the recommendation the fit without that covariate gives. + (#76) +* Added a warning from `lago_optimization()` when a binary outcome's estimated + outcome is reported outside `[0, 1]`, which happens when an identity-link + linear probability model is extrapolated to an intervention beyond the range + its components were fitted over. The estimate is not clamped, because it + drives the optimizer and the recommendation, so the warning names the + extrapolation and reports how many interval bounds are affected while every + returned value is unchanged. (#75) +* Added a warning when a numeric additional covariate whose observed range + excludes 0 is held at 0 to compute the confidence set, naming each such + covariate and its observed range, since the reported outcome and interval are + then an extrapolation to a covariate value that never occurs in the data. The + covariate is still held at 0, so no returned value changes. (#75) * Added runnable `@examples` to every exported function that lacked them: `get_confidence_set()` and the `print()`, `summary()`, and `plot()` methods for `"lago"` objects. Every exported function now ships an example. From 55398f9fb25fb98b48d697caef4a25d7367cfb87 Mon Sep 17 00:00:00 2001 From: Ante Bing Date: Mon, 10 Aug 2026 19:40:09 +0000 Subject: [PATCH 2/3] Bump version to 1.1 --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1ecd46b..31ea06f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: LAGO Type: Package Title: LAGO -Version: 1.0.12 +Version: 1.1 Author: Ante Bing, Minh Bui, Jingyu Cui Maintainer: Ante Bing Description: Calculates LAGO recommended interventions for the next stage. diff --git a/NEWS.md b/NEWS.md index df59ce9..08ef22e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# LAGO 1.0.12 +# LAGO 1.1 * Fixed `outcome_goal_intention = "minimize"` ignoring the outcome goal. The minimize direction is implemented by negating the fitted coefficients and From 1af5679fe8f771c6862471fa961a74e36f738933 Mon Sep 17 00:00:00 2001 From: Ante Bing Date: Mon, 10 Aug 2026 19:40:38 +0000 Subject: [PATCH 3/3] Use 1.1.0 for the version --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 31ea06f..b58b211 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: LAGO Type: Package Title: LAGO -Version: 1.1 +Version: 1.1.0 Author: Ante Bing, Minh Bui, Jingyu Cui Maintainer: Ante Bing Description: Calculates LAGO recommended interventions for the next stage. diff --git a/NEWS.md b/NEWS.md index 08ef22e..829004b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# LAGO 1.1 +# LAGO 1.1.0 * Fixed `outcome_goal_intention = "minimize"` ignoring the outcome goal. The minimize direction is implemented by negating the fitted coefficients and