Repository navigation
Conversation
Sets up an empty but checkable package so that the CI pipeline itself is validated before any code depends on it. Contents: `DESCRIPTION`, `NAMESPACE`, licence, `NEWS.md`, the five hubverse workflows with SHA-pinned actions, `.lintr`, `air.toml`, `codecov.yml`, `_pkgdown.yml` and the `.github` community files, all adapted from `hubEvals`. What this proves: the check matrix runs on all five platforms, `lintr` and `air format --check` gate as intended, and the pkgdown Netlify preview builds. Heavier dependency resolution (`arrow`, `hubUtils`, `hubExamples` from r-universe) first gets exercised in the following PRs, as each adds only the `Imports` it actually uses. Licence is GPL-3 rather than the hubverse-standard MIT because this package is a derivative work of `aaronger/alloscore`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
reichlab repositories publish pkgdown sites to GitHub Pages rather than Netlify, so replace the Netlify PR-preview workflow inherited from hubEvals with the standard r-lib pkgdown workflow, matching reichlab/distfromq. The Netlify workflow could not pass here: the deploy step is configured with fails-without-credentials: true and this repository has no NETLIFY_AUTH_TOKEN or NETLIFY_SITE_ID. The site itself built fine, so the failure was purely a missing third-party credential. pkgdown still builds on every pull request, so a broken site is still caught in review; it now deploys to the gh-pages branch on push to main and on release. Actions remain SHA-pinned per hubverse security policy, which distfromq's copy does not do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The hub-agnostic core: the budget-constrained optimizer and the score built on it. `allocate()` solves `min_x sum_i E L_i(x_i, Y_i)` subject to `sum_i w_i x_i <= K` by bisecting on one Lagrange multiplier, the shadow price of the budget, so each allocation is a predictive quantile discounted by that price. `alloscore()` then charges the realized loss of that allocation against the loss of an oracle that knew the outcomes. Verification, where the original package had a single `expect_equal(2 * 2, 4)` placeholder: * Unit tests for every exported function, including closed-form checks of the expected losses against the analytic normal formulae and finite-difference checks of their derivatives. * `test-zxh.R` reproduces the published optima in Zhang, Xu and Hua (2009), which the `zxh_tab2` and `zxh_tab3` datasets carry in their `Opt` column. That is ground truth external to both versions of this package. `data-raw/zxh.R` transcribes those tables and reproduces the original `.rda` files exactly. Bug fixes are listed in `NEWS.md`. Before writing the tests I compared each ported function against the original directly: every loss function, `pdqr` builder and `allocate()` path is bit-identical, including the negative-`kappa` case the optimizer relies on and the `g = log(x)` / `alpha = 1` special case. PR 4 pins that in CI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
nickreich
force-pushed
the
nr/core-port/2
branch
from
September 2, 2026 20:01
aca2ec2 to
14cd2d7
Compare
nickreich
force-pushed
the
nr/scaffolding/1
branch
from
September 2, 2026 20:29
6de5187 to
93c8fdb
Compare
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The hub-agnostic core: the budget-constrained optimizer and the score built on
it.
Stacked on #1 — this PR targets
nr/scaffolding/1, so the diff shows onlythis layer. GitHub will retarget it to
mainautomatically once #1 merges.What it does
allocate()solveswhere each
L_iis a generalized piecewise linear (pinball) loss. The problemis separable and convex, so at the optimum every target receiving a positive
allocation has the same marginal expected benefit.
allocate()bisects on thatcommon value — the shadow price of the budget — which makes each allocation a
predictive quantile discounted by that price. All values of
Kare solvedsimultaneously, sharing root-finding work wherever they currently agree on the
multiplier.
alloscore()then charges the realized loss of that allocation against the lossof an oracle that knew the outcomes, so a perfect forecast scores zero.
Verification
The original package had exactly one test, the
usethisplaceholderexpect_equal(2 * 2, 4). This PR adds 306.the expected losses against the analytic normal formulae, finite-difference
checks of their derivatives, and a check that the unconstrained optimum is the
alpha-quantile.test-zxh.Rreproduces published optima. Thezxh_tab2andzxh_tab3datasets carry the optimal solutions to two budget-constrained multiproduct
newsboy problems from Zhang, Xu and Hua (2009) in their
Optcolumn, so thisis ground truth external to both versions of the package.
allocate()reproduces Table 2 to within 0.06 of a unit and picks out exactly the 6 of 17
products that ZXH stock.
data-raw/zxh.Rtranscribes both tables andreproduces the original
.rdafiles exactly.Before writing any of it I compared each ported function against the original
directly: every loss function,
pdqrbuilder andallocate()path isbit-identical (
max|diff| = 0), including the negative-kappacase theoptimizer relies on, the
distfromqpath, and theg = log(x)/alpha = 1special case. PR 4 freezes that into CI fixtures.
Bug fixes
Listed in
NEWS.md. The substantive ones: theO/Ucost parameterizationerrored or silently returned
NULL;dgandexp_gpl_loss_fun()'soffsetwere accepted and ignored;
new_gpl_df()referred to an undefined variable;alloscore.slim()ignoredagainst_oracle;allocate()returned an unusableobject when no target had any marginal benefit; and every dplyr and tidyr call
is now namespaced and declared, where the original only worked with the
tidyverse attached.
Known limitations, filed rather than fixed
Three pre-existing behaviours are pinned by tests rather than changed, so that
altering them has to be deliberate: #3 (negative allocations when the
alpha-quantile is negative), #4 (the oracle spends the whole budget even whenit has no use for it) and #5 (
g = "log(x)"cannot be bracketed). #1 and #2 arealso visible from this layer.
Verified locally
R CMD check: Status: OK. 306 tests, 0 failures, 0 warnings, 0 skips.lintr: 0 lints.air format . --check: clean.