Changelog
Source:NEWS.md
hvtiRlifetables 0.1.5
Documentation
The missing-
vintageerror,?us_matchedand the README now say the SAS macro’s default moved twice, fromtable84totable2008and then totable2023, rather than once straight totable2023.HANDOFF.mdrecords both moves; the shorter account undercounted the provenances a re-run job can have.DESCRIPTIONnow declares the Quarto command line tool inSystemRequirements, which the new vignette needs to build.New Overview vignette,
vignette("hvtiRlifetables"), walks a synthetic cohort fromus_lifetable_vintages()throughus_matched()tous_cohort_curve(), with and without a reporting group, and says what thenonwhite_meaningcolumn means for anything a reader will see. On the pkgdown site, articles put the table of contents on the left and use the full window width, as the other HVTI packages do (pkgdown/extra.css).
hvtiRlifetables 0.1.4
Documentation
The README now reports the completed production SAS acceptance evidence and distinguishes it from the remaining repeatable-test gap. Operational docs now list all four exported functions, including
us_cohort_curve().-
Roxygen markdown is now enabled, so the help pages render as written. Without
Roxygen: list(markdown = TRUE), 129 backtick spans, 10 bold spans and 6[fn()]cross-references reachedman/as literal text, in?us_matched, the PDF manual and the pkgdown site. Four of the six dead links pointed atus_lifetable_vintages(), the page that says what a stratum code actually means. All six now link. (#20)Nothing caught it: literal backticks are legal Rd, so
R CMD check, pkgdown anddocs-currentall passed.lint.yamlnow fails when a backtick,**or[fn()]reachesman/. Publishing a release no longer redeploys the pkgdown site. The
pkgdownworkflow deployed the tagged commit on every published release, so a release cut whilemainwas ahead rolled the site back. v0.1.3 did that on 2026-09-11: the literal backticks and dead links fixed above came back until the site was redeployed frommain. A release here only tags a commit that merging has already deployed, so the site now documentsmain. (#29)
hvtiRlifetables 0.1.3
Bug fixes
-
The
::regression tests could report a result they could not stand behind. The tests added in 0.1.2 run in a subprocess, which is the only way to catch the issue #18 defect — but a fresh R loads the installed copy of the package, never the source under development. Underdevtools::test()the parent is aload_all()session, so the two can differ, and both directions mislead: a stale install fails against correct source, and a good install passes against source someone has just broken. The second is the same shape of defect as issue #18 itself — a test that looks like it covers the code while reporting on something else.Each subprocess now fingerprints what it loaded — every object in the namespace, deparsed, plus the shipped dataset — and the test skips unless that is the code under test. The fingerprint is code identity rather than a version string, so source edited without a version bump is caught too, which is the case that produced a false pass.
-
The
::tests ran on Linux only, and nothing said so. They skipped on every macOS and Windows CI job —SKIP 5 | PASS 474against Linux’sSKIP 0 | PASS 483— while all ten checks stayed green. A skip is the one failure mode a passing check cannot show you, and on Windows the issue #18 guard had never run at all since 0.1.2. Three causes, found in that order:-
detached_r()looked forRscriptinR.home("bin"), where Windows hasRscript.exe. The extension is now chosen per platform. - The child was then launched via
-e, and with the guard above fixed it launched and produced no output at all. Two causes were proposed for that and both are false, measured rather than reasoned:shQuote()already defaults totype = "cmd"on Windows, and the payload is 860 characters againstcmd’s 8191-char cap. What the payload does carry is 14 literal newlines — it is a deparsed function — and a Windows command line cannot carry one; that is the best available explanation and is not itself measured, no Windows machine being to hand. The code is handed over as a script file now, which is platform-neutral regardless of which of those was the mechanism, andR_LIBSis set on the parent and inherited rather than passed throughsystem2(env=), which Windows does not support. - The fingerprint was locale-dependent, in two independent ways.
R CMD checkforcesLC_COLLATE=Con the parent while a--vanillachild inherits the machine’s locale:sort()then orders the namespace differently —VINTAGE_METAsorts third underCand last underen_US, which ignores case — andsaveRDS()version 3 writes the session’s native encoding into its header, so identical data serialises to different bytes. Same package, two fingerprints. Nowsort(method = "radix")andsaveRDS(version = 2), both byte-ordered and neither locale-aware.
The fingerprint is now identical under
C,en_US.UTF-8andde_DE.UTF-8. -
Documentation
-
The README carries the family’s badge block. It had none. It now shows R CMD check, test coverage, repository status, the pkgdown site, the GitHub version and lint, in the order the other
hvtiR*packages use. Four report on CI this repository already ran; the other two show its repository status and the version inDESCRIPTION. Nothing new was wired up. (#27)
Repository
-
Issues open from forms. A bug report asks for the function, a reproducible example, the expected result,
sessionInfo()and how the package was installed. That last one is not boilerplate: family versions reach GitHub before CRAN, so an install can be behind the version a bug was fixed in. Installation problems are routed tohvtiR, the family installer, whose form collects the diagnostics an install failure needs. (#26)
hvtiRlifetables 0.1.2
Bug fixes
-
Every export failed when called with
::.hvtiRlifetables::us_matched()and its two siblings errored withobject 'us_lifetable_models' not foundunless the package had first been attached withlibrary(). The functions referenced the shipped dataset by bare name, and a lazy-loaded dataset is promised into the package environment rather than the namespace — which is not on the parent chain package code resolves against. It worked only because every caller so far happened to attach the package first. The dataset is now loaded explicitly by an internal accessor and stays user-visible; nothing about the fitted models or the numbers changes. (#18)The regression test runs in a subprocess with the package unattached.
tests/testthat.Rcallslibrary(hvtiRlifetables)beforetest_check(), so an ordinary test intests/testthat/runs attached and passes against the broken code — which is how this survived to 0.1.1.
New features
-
us_cohort_curve()reduces the per-patient output ofus_matched()to the cohort curve a figure actually carries, and withbygives one curve per group of the caller’s own choosing — age band, treatment arm, era. (#16, #17)byis a reporting grouping and is independent oftable=, which chooses which strata the life table itself is built from. A report broken down by age band is normally still matched on"sexrace".The cohort average already existed as
us_matched(individual = FALSE), and its arithmetic is unchanged — that call now routes throughus_cohort_curve(), so the two cannot drift into two different averages. What is new is that the reduction is reachable without recomputing the curves, and that it takes a grouping. Studies deriving the average inline can now call it instead, which is the point: the choice of what to average is made once, here, and documented.
hvtiRlifetables 0.1.1
Documentation and metadata only. No change to us_matched(), the vintages, or the shipped fitted models — results are identical to 0.1.0.
- The pkgdown site is live at https://ehrlinger.github.io/hvtiRlifetables/ and is now listed in
DESCRIPTION. GitHub Pages had never been enabled on this repository, so the site 404’d even though thepkgdownworkflow had been deploying to thegh-pagesbranch successfully since 2026-08-20. A green deploy is not evidence that a site serves.
hvtiRlifetables 0.1.0
First release. Reproduces the Cleveland Clinic SAS macro %usmatchd in R.
New features
-
us_matched()returns age, sex and race matched US reference survival and its hazard, for individual patients or as a cohort mean curve. Argument names and thetable=modes mirror the macro so a SAS job translates by inspection. -
us_lifetable_vintages()reports the available vintages with their provenance and, importantly, what each vintage’s non-white stratum actually contains. -
us_lifetable_model()returns a single fitted parameter set for inspection. - Ships
us_lifetable_models: 27 fitted three-phase hazard parameter sets — nine strata acrosstable84,table2008andtable2023— with their_STATUS_gates, fitted-form flags and covariance blocks.
What is and is not in this repository
The package ships the derived dataset data/us_lifetable_models.rda. CCF’s source .sas7bdat fitted blocks are not tracked here: they were removed from git history and are .gitignored, because this repository is public. data-raw/ carries the build script and the %usmatchd macro variants, not the blocks themselves. Rebuilding the dataset requires restoring those inputs from the share; data-raw/build-models.R names the location and errors loudly if they are absent.
Design notes
-
vintagehas no default. Omitting it is an error listing the available vintages. The macro’s own default silently moved twice, fromtable84totable2008and then totable2023, and jobs re-run across either move got different numbers with no signal. -
hmatchedis per year regardless ofscale, matching the macro’s source rather than its header comment. See the README. - The
table2023non-white stratum is stored under codebbut is a risk-weighted average of Black, Asian, American Indian and Hispanic death rates. It is not Black. The macro’s comment says otherwise and is wrong. - Both evaluators error rather than return a non-finite value.
TemporalHazard’s early phase is indeterminate at exactly age 0 (0 * Inf), which affects 9 of the 27 shipped strata. - An empty cohort returns a zero-row data frame with the documented columns, not
NULL. Unsortedtimesare rejected rather than silently sorted. - Covariance blocks ship but nothing reads them. They are the only route to a confidence band later.