serocalculator (development version)
Bug fixes
est_seroincidence()’scluster_varargument can now be pointed at the subject id (e.g.cluster_var = ids_varname(pop_data)) to get a cluster-robust standard error for a multi-biomarker fit that accounts for within-person correlation across biomarkers.log_likelihood()combines biomarkers by summing their marginal log-likelihoods, which understates the true variance when biomarker readings from the same person are correlated, as expected when they share an infection history — see #637. A verbose fit with more than oneantigen_isosand nocluster_varnow says so, and names the id column to pass. The default behavior (nocluster_var) is unchanged, and its standard error is unaffected. (#645)- Restored participant linkage across biomarker rows in the SEES cross-sectional data and bundled examples. Public IDs are newly generated pseudonyms; the restricted source identifier is never written to package artifacts.
as_pop_data()andset_id_var()now clarify that their ID column must identify people rather than individual observations. (#650)
New features
- Added
sim_pop_data_multi_cached()andest_seroincidence_by_cached(), caching wrappers around the two most computationally expensive functions in the package. The first call computes and saves the result; later calls with the same arguments load it instead of recomputing. The cache is keyed on the arguments, so changing any of them recomputes automatically. Passcache_rerun = TRUEto force recomputation. Cache-control arguments carry acache_prefix so the wrapped functions’ ownverboseargument remains reachable. (#631) - Added
refit_strata(), which re-fits a chosen subset of strata with log-likelihood graphs attached. It is the companion to caching a large fit withbuild_graph = FALSE: graphs are attached per stratum, so they make a cached fit far larger on disk, and the usual pattern is to cache without them and re-fit only the strata you want to plot. Strata are selected by the columns that define them rather than by index, becausecount_strata()names strata positionally and a subset renumbers them. (#632) - Added interactive Shiny app
curve_app()for visualizing antigen-antibody kinetics models with real-time parameter sliders (#392). - Added
antibody_decay_curve()andpathogen_decay_curve()functions for simulating antibody and pathogen decay over time (#392). - Added
plot_decay_curve()for plotting decay functions using ggplot2 (#392). - Added helper functions
t1f()(time to end of active infection) andy1f()(peak antibody concentration) (#392). autoplot.sim_results()gainsx_var,group_var, andcolor_vararguments, letting users choose which columns map to the x-axis, group, and color aesthetics instead of the previous hardcodedsample_size/lambda.simmapping.graph.curve.params()now uses the 5-parameterab_5p()antibody response model and supportsunits-aware curve parameters. (#393)- Added
ab_5p(), a 5-parameter antibody response model that supports {units}-aware inputs (e.g.t = units::as_units(50, "days")), building on the existingbt()active-phase helper. CI now installs the systemudunits2library on macOS and Windows so the newunitsdependency can compile there. (#393) - Added
sim_pop_data_2(), asim_pop_data()alternative built onab_5p()that simulates each simulated individual’s age (sim_age()) and time since their last seroconversion (sim_time_since_last_sc()) directly, rather than simulating an infection history. Both new helper functions, andsim_pop_data_2()itself, acceptunits-aware inputs. sim_pop_data_multi()gained asim_functionparameter (defaultsim_pop_data) so callers can selectsim_pop_data_2()instead. (#393)
Documentation
Split the methodology article’s combined “Likelihood and log-likelihood” definition into two separate, independently cross-referenceable definitions (
#def-likelihood,#def-log-likelihood) — previously only the likelihood half had its own citable id.Formalized the “Cluster-robust standard errors” section of the methodology article: the sandwich estimator now cites Huber (1967), White (1980), and the clustered-data extension by Liang and Zeger (1986), and the Hessian, score function, and other definitions and results in that chapter are now stated as numbered, cross-referenced Quarto theorem/definition divs instead of informal prose.
The methodology, scrub typhus, and antibody-response-model articles no longer fetch their example data from OSF at render time — the docs build was failing whenever OSF was unavailable, on PRs that never touched the affected vignettes.
n6cp3,hqy4v,u5gxh, andh5js4are now vendored undervignettes/precomputed/osf/; the two chunks that only neededrtw5kfiltered toiter < 50now filter the already-bundledtyphoid_curves_nostrat_100instead, since the two are identical once filtered, so no separate copy ofrtw5kneeded vendoring. (#648)Removed maintainer-facing implementation notes (OSF/vendoring rationale, an internal variable-naming decision, why
est_seroincidence_by_cached()is called withbuild_graph = FALSE) from the R comments the methodology article renders on the website, replacing them with reader-facing comments. The notes worth keeping for future editors but with no reader-facing equivalent moved into HTML comments, invisible on the published page; a couple of purely build-time asides (e.g. “no network access needed”) were dropped outright as no longer worth keeping.Listed
sim_pop_data_multi_cached(),est_seroincidence_by_cached(), andrefit_strata()in the documentation site’s reference index. All three were exported and had help pages, but no section ofaltdoc/reference.ymlclaimed them, so they were unreachable from the reference index and the sidebar and fell into the trailing “Other” group. Surfaced byaltdoc::render_docs(), which warns about an unclaimed non-internal topic; no CI check covers this. (#632)Merged the “Simulation studies” article (
vignettes/articles/simulate_xsectionalData.qmd) into the methodology article, which now demonstrates live everything it describes. The methodology article previously showedserocalculatorcode in non-executing chunks and closed with a static screenshot of the simulation article’s recovery study, while the simulation article ran that code without deriving the theory behind it. The estimation walkthrough now runs on simulated data where the true rate is known, and the validation section runs the full multi-cluster recovery study, thenlm()convergence checks,analyze_sims(), and therenew_paramsbias caveat. The retired article’s URL redirects to the merged one. (#632)The methodology article’s simulations are cached to
vignettes/precomputed/via the new*_cached()wrappers, so a docs build reuses them instead of recomputing once per output format. Its simulation sections now use the bundledtyphoid_curves_nostrat_100rather than downloading the same curve parameters from OSF; the two are identical once filtered.The methodology article’s reveal.js slides now show code, folded away by default, instead of hiding it. The Word output hides code by default, except in the demonstration chunks that are never evaluated, which mark themselves
echo: trueso those sections do not render empty.Ported the full Quarto extension set from
Morrison-Lab/rptintoaltdoc/_extensions/, registered project-wide inaltdoc/quarto_website.yml’s newfilters:list:d-morrison/div-anchorsandd-morrison/equation-anchorsadd hover permalinks to theorem/definition divs and numbered equations;sun123zxy/callouty-theorem(+coatless-quarto/custom-callout) render themethodologyvignette’s existing#def-/#exm-divs as colored callout boxes instead of plain numbered text;d-morrison/revealjs-html-linksadds a link back to the standalone HTML page on themethodologyvignette’s RevealJS slides. Theslidebreakextension (already in use) moved fromvignettes/_extensions/toaltdoc/_extensions/alongside the rest, so it too is now a project-level filter instead of a per-document one. (#585, #586, #587, #588, #589)Took the sidebar fold control from
altdocinstead of keeping a copy here.altdoc/sidebar-fold.htmland the matching block inaltdoc/styles.cssare replaced byinclude-in-header: $ALTDOC_SIDEBAR_FOLD, whichaltdocstages at render time with script and style together. The same pair had been copied intoucdavis/bcs, and the two copies had already drifted – this repo changed its copy to start folded and nothing carried that across. The sidebar still starts folded, now viasidebar_fold: collapsedinaltdoc/reference.yml, so what used to be a source-level divergence is a one-line setting.Declared the reference manual’s grouping once, in a new
altdoc/reference.yml(#610). It used to live in two hand-maintained places that nothing kept in step: thealtdoc/reference.qmdindex page and theReferenceblock ofaltdoc/quarto_website.yml. Adding a topic to one and missing the other rendered cleanly and raised no warning, which is how it went unnoticed on #392. altdoc now builds both surfaces from the single file, so the two cannot disagree, and warns about any exported topic no section claims rather than leaving it off the site in silence. The published grouping is unchanged: the same nine sections, the same 42 topics, in the same order.Moved the
altdocdependency off therecursive-qmd-searchbranch and onto the default branch, which is what supplies the grouped sidebar above. That branch has no commits the default branch does not already contain, so it was holding the docs build behind for nothing. The branch was named in three places –Remotes,Config/Needs/website, and ther-packagesinput of the docs workflow – and changing one of them alone makes the build fail to resolve rather than fall back, sincepakreads the two as conflicting requirements for the same package.Started showing each topic’s name alongside its title in the sidebar. Titles alone left
as_pop_dataandload_pop_dataas adjacent entries reading identically, and the same foras_noise_paramsandload_noise_params, with nothing to tell a reader which was which.Stopped
.gitignorefrom hiding new files added underaltdoc/. A barealtdocentry ignored the whole source directory; the files already in it stayed tracked only because they predate the rule, so the omission was invisible until a new one was added and silently skipped bygit add.altdoc/.gitignorealready covers the real build artifacts there (_site/,.quarto/,pkgdown.yml,freeze.rds), and_quartois still ignored separately, so the entry protected nothing.Added a control that folds the documentation website’s sidebar away, giving the content the width it held (#622). Quarto’s
collapse-levelfolds sections within the sidebar; it has no control for the sidebar itself on a website, so the sidebar held a fixed grid column at every viewport wide enough to show it. The new navbar button hides it and moves the content’s grid start line into the vacated columns, which at a1400pxviewport widens the content from630pxto922px. The state is kept inlocalStorage, so it survives navigation between pages. The script that restores it is included in the page header rather than after the body, so a folded sidebar never flashes into view. Below Quarto’s992pxbreakpoint the button is hidden: the sidebar is already a drawer laid over the content there, so it holds no width to reclaim.The documentation website’s sidebar now starts folded. Readers arrive on a page to read it, and the navbar already carries the same destinations, so the wider content column is the better default; unfolding the sidebar is remembered, so the choice is still made once per reader rather than once per page.
Fixed two dead external links. The
methodologyarticle credited the Salmonella Typhi photo to a Wikimedia Commons page that was deleted on 2026-03-11; the deletion discussion confirms the image is CDC/PHIL public-domain work (PHIL ID 2115), so the credit now cites PHIL directly instead of the dead page. The Ubuntu R install snippet in.github/copilot-instructions.mdfetchedpubkey.gpg, which CRAN no longer serves (404); it now usesmarutter_pubkey.asc.Figures on the documentation website now open an enlarged lightbox view when selected. Enabled site-wide (
lightbox: true) across every format, including the revealjs slides, and covering both cross-referenced figures and plain images (#584).Restored the R code in the documentation website’s vignettes and articles.
vignettes/_metadata.ymlsetecho: falsefor thehtmlanddocxformats, which applied to every file undervignettes/, so the published tutorials rendered as prose and figures with no code at all, and themethodologyarticle’s “Estimating seroincidence” section — whose only content is a non-evaluated code chunk — rendered as an empty heading.Reviewed and revised the
methodologyarticle: corrected the standard-error description (the inverse negative Hessian is the variance, not the standard error) and the “truncated by age” characterization of the latent infection-time distribution, added narrative to the previously code-only “Estimating seroincidence” and “Multiple biomarkers” sections, moved “In-progress work” out of the “Validation” section into its own section, promoted “References” to a top-level section, and restored the captions and image credits on the two typhoid figures (adjacent images with no blank line between them are parsed as one paragraph, which drops their captions).Fixed dead documentation links that still used the old pkgdown site layout. The site root is now a redirect page, so
/articles/…,/reference/index.html,/news/index.html, and/CONTRIBUTING.htmlno longer resolve; links from within the site are now relative so they stay on the reader’s docs version, and the links in the README point at paths that exist. Also corrected the description in the README of which URL serves which docs version, and fixed the link to the contributing guide in the pull request template.Fixed a dead link in the README: the in-development documentation pointed at
/main/, which has served nothing since #504 moved development docs to/dev/. Also removed a duplicated “the” in the same sentence. (#604)The documentation site now deploys multiple versions side by side, following
rpt’s pattern: pushes tomaindeploy development docs to/dev/, published releases deploy stable docs to/latest-tag/(plus an archived/vX.Y.Z/copy), and the site root redirects to whichever was deployed most recently. A “Versions” navbar dropdown links between them. (#504)Updated the documentation site configuration to promote “Get started”, “Reference”, and “News” in the top navigation, and added a grouped
reference.qmdindex plus grouped sidebar reference sections that exclude internal-only topics.The documentation site’s reference index page is now titled “Package index” rather than “Reference”, matching the old pkgdown site and distinguishing the page from the navigation entry that links to it. (#594)
Added a “Citation” entry to the documentation site’s sidebar. The citation page was previously reachable only from the navbar “More” dropdown, unlike
rptand the default sidebaraltdocships, which both list it. (#594)Links to the documentation site’s old
/main/paths now resolve again. Before the altdoc migration the development docs were published under the branch name, so they lived at/main/; they now live at/dev/, which left every/main/...link dead. The site now serves a root404.htmlthat redirects any request under/main/to the same path under/dev/, deep links included. Redirection requires JavaScript; without it the page renders as a plain not-found notice linking to the documentation home page. (#599)Updated the documentation site’s dark-mode styling to match
rptby adding the same inline-code color override used there, improving contrast on the home page and article text.Added introductory lecture slides to the
methodologyvignette (“Estimating Incidence Rates from Cross-Sectional Serosurveys”).The
methodologyvignette now loads itsslidebreakshortcode explicitly so the shortcode no longer leaks into HTML output, and rendered vignettes now suppress package startup messages.Fixed the date in the vignettes’ title blocks, which rendered as “Invalid Date” (most visibly on the
methodologyslides’ title slide).vignettes/_metadata.ymlset the date with an inline R expression, but Quarto merges that file into the document metadata without aknitrpass, so the expression was never evaluated; the date now uses Quarto’s owntodaykeyword. (#597)Restored the
methodologyvignette’s docx download link, which had been dropped on the (mistaken) assumption that it needed its owndocx:format block; it renders fine via thedocx:default already declared invignettes/_metadata.yml.Completed the measurement-noise model in the
methodologyvignette (multiplicative relative error), added a “Combined biological and measurement noise” section, and added a “Noise and never-infected subjects” section explaining that additive biological noise spreads a never-infected subject’s measured response over a positive range while multiplicative measurement noise leaves a true zero at zero. (#561)Corrected the documentation of the
epsmeasurement-noise parameter (inexample_noise_params_pk/example_noise_params_seesand the vignettes):epsis the bound on the relative measurement error (Unif(-eps, eps)), not a coefficient of variation. A measured CV corresponds toeps = sqrt(3) * CV. (#563)Added the never-infected density under combined biological and measurement noise to the
methodologyvignette: the piecewise closed form fory_obs = eps_b * (1 + xi), matching Teunis and van Eijkeren (2020) Equation 19 and verified to integrate to the never-infected probability. (#567)Made the never-infected term explicit in the “per-person likelihood” slide of the
methodologyvignette: the observed-data likelihood integral is now shown split into its continuous (ever-infected) and discrete (T = NA, never-infected) parts, withp(Y=y | T=NA)defined as a point mass at zero (before noise). (#567)Explained, in the “Biological noise” section of the
methodologyvignette, why the biological-noise widthnuis estimated as the 95th percentile of negative controls: Teunis and van Eijkeren (2020) show that a uniform noise model only needs to match the true noise distribution’s width, not its exact shape, and note that this width is difficult to verify against a mixed (ongoing-seroresponse) population – motivating estimation from a clean negative-control panel instead. Also noted that the specific choice of the 95th percentile (rather than, e.g., the 99th or the sample maximum) is an adopted convention, not a result derived or optimized in the paper. (#567)Added the conditional variance
Var(y_obs | y_true)for the combined biological- and measurement-noise model to themethodologyvignette, derived from the independent-product-variance identity and checked against both single-source special cases already in the vignette. (#571)Added
Var(y_obs | T=t), marginalizing over between-person heterogeneity iny_true, to themethodologyvignette: derived via the law of total variance from theVar(y_obs | y_true)formula above, with the between-person heterogeneity termVar(y_true | T=t)introduced symbolically (it has no closed form in this framework, sinceserodynamicsrepresents curve-parameter heterogeneity as an empirical posterior sample rather than a stated parametric distribution). Clarified that the longitudinal model’s residual variance is constant on the log scale conditional on individual random effects, while random waning rates can induce time-varying marginal population variance thatserocalculatorcarries forward by averaging over kinetic-parameter draws. (#571)Moved
f_dev0()’s@examplesblock to a separate example file (inst/examples/exm-f_dev.R), following the convention already used by other functions in this package. (#393)
Internal
- Added a regression test locking in that multi-biomarker
log_likelihood()equals the sum of the per-biomarker values. This is the composite (independence) likelihood behavior described in #637: the code sums per-biomarker marginal log-likelihoods rather than integrating a shared latent infection time, and this identity should not change silently if that ever does. (#637) - Regenerated
NAMESPACEandDESCRIPTIONwithroxygen28.1.0, which groups each package’simportFrom()symbols into a single multi-line directive instead of one directive per symbol. The change is purely one of formatting: the exports, the S3 method registrations, the compiled-library declaration, and all 75 imports are unchanged.docs-checkregenerates the documentation and fails when a tracked file differs afterward, so every run of it sinceroxygen28.1.0 was published on 2026-08-04 had failed. Greendocs-checkruns on other open pull requests are stale rather than contradictory: each of them predates that release. (#636) - Disabled the
@claudeagent bot..github/workflows/claude.yml’s reactive triggers are commented out and its job carriesif: false, so no comment, issue, or review event invokes the agent, and neither does a manual dispatch (the reusable workflow runs unattended onworkflow_dispatchby design). Reviews are the only Claude capability left, and they run on request only: automatic review on pull-request activity is off, and a review starts when a collaborator comments/reviewon a pull request. That dispatch now pins the review run to the pull request’s head branch, so its check-run lands on the right commit. - Fixed two dead provenance links in workflow comments.
check-readme.yamlcited a file that was deleted fromIndrajeetPatil/statsExpressions’s default branch when its CI moved to reusable workflows; the citation is now pinned to a commit where the file exists.test-coverage.yamlcited a GitHub Actions run URL, which expires after roughly 90 days; it now cites the upstream workflow file. - Removed
.github/CONTRIBUTING.Rmd;.github/CONTRIBUTING.mdis now the hand-maintained source. The.Rmdexecuted no code (its only chunk waseval = FALSE), so it rendered to markdown identical to a hand-written file while adding a source/generated pair with no CI check to keep the two in sync. (#613) - Documentation website now renders HTML (primary), docx (download link on every page), and revealjs (slides for
methodology.qmd) formats. Fixed the HTML/revealjs output-filename collision by specifyingoutput-file: methodology-slides.htmlfor revealjs inmethodology.qmd’s frontmatter; docx goes in_metadata.ymlglobally since.docxhas no collision risk. (#503) - Added Codex repository guidance and R-package workflow skills. (#574)
news.yamlnow calls the centrald-morrison/ghacheck-news.yml@v2reusable workflow (bumped from the initial@v1pin, which predated gha’s fix for this repo’sno-changeloglabel convention) instead of invokingUCD-SERG/changelog-check-action@v2directly. (#537, #593)claude.ymlandclaude-code-review.ymlnow call the centrald-morrison/ghaclaude.yml@v2andclaude-code-review.yml@v2reusable workflows instead of carrying their own copy of the agent/review machinery. (#549)docs.yamlnow calls the centrald-morrison/ghaaltdoc-multiversion-docs.yml@v2reusable workflow instead of carrying its own ~360-line copy of the build/deploy logic, and the local.github/scripts/generate_version_dropdown.pyandgenerate_multiversion_landing_page.pycopies are deleted in favor of the composite actions in that repo. Fixes made centrally now reach this package instead of stopping atrpt. Rewrote.github/MULTI_VERSION_DOCS.md, which still described thepkgdownsetup replaced during the altdoc migration. (#595)- The
methodologyvignette’s LaTeX macros now come from the sharedd-morrison/macrosgit submodule (included via{{< include ../macros/macros.qmd >}}) instead of a localvignettes/articles/_macros.qmd. The deck adopts the shared macro vocabulary (e.g.\densfor the density function in place of the local\pdf). (#534) claude-code-review.ymlnow setsallowed_bots: github-actions[bot]so the review still runs (and posts feedback) whenclaude.ymlre-dispatches it on an@claude reviewcomment; previously the bot-initiated dispatch aborted with “Workflow initiated by non-human actor”.claude.ymlnow grants the@claudeagent the file tools (Read/Glob/Grep/Edit/MultiEdit/Write) in--allowedTools; previously the agent could run checks/git/gh but not edit files, so it fell back to posting diffs for manual application.- Added the
iterateClaude Code skill (.claude/skills/iterate/) for driving a PR to a clean review verdict. - Ported the
@claudeagent and PR-review GitHub Actions workflows (plus Claude/Copilot config:CLAUDE.md,.claude/settings and slash commands, and path-scoped.github/instructions/) from the UCD-SERGqwttemplate, adapted to this package. (#523) - Claude PR review workflow now skips (rather than hard-failing) when triggered by a bot (e.g.
claude[bot]pushing a commit). (#519) - Added the
lint-changed-linesCI workflow (calling the reusabled-morrison/ghalint-changed-lines.yml@v2workflow), which flags lint issues only on the lines a PR actually adds or modifies (rather than whole changed files, aslint-changed-filesdoes). This lets lint rules be adopted or tightened incrementally as code is touched, instead of forcing a repo-wide reformat. Intended to replacelint-changed-filesas the lint gate once branch protection is updated to require it. (#558) - Removed
docs.yaml’s job-levelconcurrency:group, which resolved to the same string as the workflow-level group on every non-pull_requestevent and so deadlocked thedocsjob: the run already held that group, so the job could never acquire it and was failed instantly with no logs. This blocked every versioned documentation deploy (/dev/,/latest-tag/,/vX.Y.Z/). The workflow-level group already serializes runs by PR number or ref. (#590)
Bug fixes
sim_pop_data()andsim_pop_data_multi()now produce identical results across operating systems. Simulated inter-infection times are now rounded to whole days, so the number of random draws consumed no longer depends on platform-specific floating-point results oflog()(which previously shifted the random-number stream out of sync and made simulated values, and their snapshots, differ between macOS, Windows, and Linux). Simulated values change slightly as a result of this fix. (#447)- Cluster-robust standard errors now treat multiple
cluster_varcolumns as multi-way clustering instead of collapsing them to a single interaction. One-way subset terms now use the CR1 small-sample correction by default, the floor to model-based variance is optional, and debug output now exposes the multi-way variance decomposition used in the final standard error. A negative multi-way variance estimate is now floored at 0 (with a warning) instead of producingNaNstandard errors, and an unavailable subset variance (for example from a degenerate Hessian) now warns and yields a missing standard error, instead of a silentNaN. Withfloor_to_standard = TRUEit falls back to the model-based variance instead, unless that variance is itself unusable (e.g. from the same degenerate Hessian), in which case it also yields a missing standard error. (#543) - Corrected default axis labels in
strat_ests_barplot()(xlab) andstrat_ests_scatterplot()(ylab) to say “seroincidence” rather than “seroconversion”/“incidence”. load_noise_params()andload_sr_params()now fail gracefully with informative messages when internet resources are unavailable, complying with CRAN policy (#505)- Added Version Crosswalk article to pkgdown website to help users migrate code from v1.3.0 to v1.4.0
- Provides clear tables comparing old and new function names
- Includes code examples showing how to update existing code
- Accessible as a prominent tab in the website navigation
autoplot.seroincidence()now raises its “graphs cannot be extracted” error viacli::cli_abort()rather thanstop(), so the message is formatted as a cross bullet naming the problem and an info bullet naming thebuild_graph = TRUEargument that was missing (#392).antibody_decay_curve(),pathogen_decay_curve(),t1f(), andy1f()now validate their parameters (non-negative values,mu_y != mu_b) and raise an informativecli::cli_abort()error instead of silently returningNaNor dividing by zero (#392).plot_decay_curve()now respects itsxmaxargument instead of always plotting tox = 100(#392).
Compatibility
- Replaced deprecated
dplyr::is.grouped_df()usage withdplyr::is_grouped_df()indf_to_array()for compatibility with newer dplyr releases.
New features (cluster-robust SE)
- Added
cluster_varandstratum_varparameters toest_seroincidence()andest_seroincidence_by()to support cluster-robust standard error estimation. Whencluster_varis specified,summary.seroincidence()automatically computes cluster-robust (sandwich) variance estimates to account for within-cluster correlation in clustered sampling designs such as household or school-based surveys. cluster_varparameter now accepts multiple variables (e.g.,c("school", "classroom")) for multi-level clustered sampling designs. Cluster-robust standard errors will account for all specified clustering levels.
Bug fixes (cluster-robust SE)
- Fixed column naming issue in
summary.seroincidence()where cluster-robust standard errors caused[]notation in column names (SE[,1]instead ofSE). - Added
se_typecolumn tosummary.seroincidence()output to clearly indicate whether “standard” or “cluster-robust” standard errors are being used. - Fixed
est_seroincidence_by()to properly pass cluster and stratum variables through to stratified analyses. Previously, these variables were dropped during data stratification, causing errors when trying to use clustering withest_seroincidence_by().
Code organization
- Refactored clustering-related code following package organization policies:
- Moved
.compute_cluster_robust_var()toR/compute_cluster_robust_var.R - Each function now in its own file for better maintainability and git history
- Moved
- Updated copilot-instructions.md with code organization policies
Dependencies
- Replaced
ggpubrwithpatchworkfor arranging multi-panel plots, removing the indirectggrepeltransitive dependency.
serocalculator 1.4.0
New features
Added support for cluster-robust standard errors in
est_seroincidence()through newcluster_varandstratum_varparameters. Whencluster_varis specified,summary.seroincidence()automatically computes cluster-robust (sandwich) variance estimates to account for within-cluster correlation in clustered sampling designs such as household or school-based surveys.Added
compare_seroincidence()function for statistical comparison of seroincidence rates- Performs two-sample z-tests to compare seroincidence estimates
- Returns
htestformat when comparing two single estimates - Returns formatted table with all pairwise comparisons for stratified estimates
- Added examples to tutorial vignette and comprehensive unit tests
Implemented multi-version pkgdown documentation with version dropdown menu
- Users can now switch between main, latest-tag, and versioned releases
- Default landing page shows latest-tag (most recent release)
- Based on insightsengineering/r-pkgdown-multiversion setup
Added
chain_coloroption tograph.curve.params()to control MCMC line color (#455)Made
graph.curve.params()the default sub-method forautoplot.curve_params()(#450)Added
log_xandlog_yoptions tograph.curve.params()sub-method forautoplot.curve_params()(#453)Extended
sim_pop_data_multi()to loop over multiple sample sizes (#444)Added new functions
analyze_sims()andautoplot.sim_results()(#444)Rename
estimate_scr()toest_seroincidence_by()(#439)Rename
estimate_scr()toest_seroincidence()(#432)Rename argument
curve_paramstosr_paramsfor estimation functions (#424)added documentation for
count_strata()(#431)Rename
as_curve_params()toas_sr_params()(#421)Rename
load_curve_params()toload_sr_params()(#421)added default for
xvarin"scatter"option forautoplot.seroincidence.by()(#417)Extended
autoplot.summary.seroincidence.by()to include types for either scatter or bar plots of stratified results (#397)added option to add lines using
group_varinput toautoplot.summary.seroincidence.by()(#410)autoplot.pop_data(type = "age-scatter")now shows legend at bottom (#407)autoplot.pop_data(type = "age-scatter")now facets by antigen isotype (#406)Rename
est.incidence.by()toestimate_scr_by()(#389)Rename
est.incidence()toestimate_scr()(#389)Improved warning messages for
get_biomarker_names_var()Added
get_*()extractor functions to API (#380)Added optional CI error bars to
autoplot.summary.seroincidence.by()(#372)Improved y-limit calculation in
graph.curve.params()(#368)Added option for
graph.curve.params()to show all curves (#368)Added color-coding for
graph.curve.params()(#383)Added
quantilesparameter tograph.curve.params()and corresponding test intest-graph.curve.params.R(#434)Removed
warn.missing.strata()from API (#366)Added more details about contributing PRs in
Contributing.md(#280)Added warnings for missing biomarker data (#168):
- completely missing antigen-isotype in a stratum
- uneven antigen-isotype counts in a stratum (likely from incomplete data)
Split dev and release websites into:
- release: https://ucd-serg.github.io/serocalculator/
- dev: https://ucd-serg.github.io/serocalculator/dev/
Fixed citations in
methodology.qmdarticle (#360)Added outline to pkgdown website (#353)
Added verbose option for
summary.seroincidence()andsummary.seroincidence.by()(#348)Extended
simulate_xsectionalData.Rmdarticle to explorerenew_params = TRUEvsrenew_params = FALSE(#348)Renamed variables for consistency (#281, #373):
sim.cs()->sim_pop_data()sim.cs.multi()->sim_pop_data_multi()
Bug fixes
Internal changes
switched
expect_snapshot_data()to an internal function due to CRAN errors (#464)generalized
ab1()added codecov/test-results-action to test-coverage.yaml workflow
added test for censored data in f_dev() (#399)
added test for
autoplot.curve_params()added test for
graph.curve.params()(#368)reverted Readme source file from qmd to Rmd.
switched pkgdown GHA from
any::pkgdowntor-lib/pkgdown(i.e., dev version) (#359)added test for
summary.seroincidence.by()(#352)Started checking for use of base pipe instead of magrittr pipe by linter (#347)
Removed
ldpar()from API (#345)Added test for
sim.cs()(#344)Added test for internal function
ab()(#342)Reverted name change
ldpar()->row_longitudinal_parameter()(#343)
serocalculator 1.3.0
New features
Removed function ‘get_additional_data()’ (#332)
Updated documentation examples to include csv files (#328)
Added csv files for use in documentation examples (#329)
Added
serocalculator_example()function to help locate example data files (#329)Fixed a bug in computing the antibody response curve when \(r=1\) (#323)
Added example datasets with documentation for examples and testing (#314)
Improved error messaging for
autoplot.pop_data()(#234).Clarified package installation instructions in scrub typhus vignette (#234).
Add
as_noise_params(#228)Updated
simulate_xsectionalData.Rmd(linting, removing deprecated functions) (#289)Added default value for
antigen_isosargument inlog_likelihood()(#286)Updated enteric fever example article with upgraded code and visualizations (#290)
Added template for reporting Issues (from
usethis::use_tidy_issue_template()) (#270)Added template for pull requests (from https://github.com/bcgov/ssdtools) (#265)
Internal changes
Updated documentation to align with previous CRAN feedback (#328)
Updated tests to use internal testing datasets instead of external links (#328)
Updated
test-coverage.ymlGHA action to currentr-libstandard (#330)Change default pipe setting (#312)
Add test for missing strata in
est.incidence.by(#227)Added
snapshot_valuetest forest.incidence()(#315)Sped up
lint-changed-filesGitHub Action (#317)Added online preview builds for PRs that change the
pkgdownwebsite (#309)Added
test-autoplot.pop_datatest (#234)initialized
lintrwithlintr::use_lint()(#278)created unit test for
df_to_array()(#276)fixed
dplyr::select()deprecation warning indf_to_array()(#276)Added
devtagto package (usingdevtag::use_devtag()) (#292)Added
@devtag to?df_to_array()(#292)Generalized
get_()andset_()methods to be general-purpose (no S3 class-specific methods needed yet) (#274).Updated GitHub Action files and reformatted
DESCRIPTION(#268)Added
.gitattributesfile (https://git-scm.com/docs/gitattributes) copied from https://github.com/tidyverse/ggplot2Added QR code to
README.qmdAdded additional automated checks through GitHub actions, including:
- check that
README.qmdstill compiles (advice from preventive-r-package-care) (#259) - check
NEWS.mdfor updated change log (#257) - lint changed files (#256)
- check that
serocalculator 1.2.0
Added
test-summary.pop_datatestModified
test-est.incidencetestAdded stratification to
summary.pop_dataAdded
verboseoption forcheck_pop_data(), changing default behavior to avoid printing an OK message.
serocalculator 1.1.0
Renamed
llik()tolog_likelihood()Renamed
fdev()tof_dev()Renamed
df.to.array()todf_to_array()Renamed
getAdditionalData()toget_additional_data()Removed
clean_pop_data()functionRemove
clean_pop_data()dependency functions documentation examplesAdded
age,value,idandstandardizearguments toload_pop_data()Added the following methods to
pop_dataclass:set_age()set_value()set_id_var()get_age()get_values()ids()get_age_var()get_values_var()ids_varname()
Added additional warnings to
load_pop_data()Added
scales::pseudo_log_trans()toautoplot.pop_data()to avoid log 0Added
test-est.incidence-status.Rtest to check output whenstandardizeoption is FALSE onload_pop_data()Replaced column name comparison on
check_pop_data()to use attribute name onpop_dataclass
serocalculator 1.0.1
- added
n_pointsargument toplot_curve_params_one_ab() - Added
type = "age-scatter"option forautoplot.pop_data()
serocalculator 1.0.0
- Moved underlying methods to
serocalculatorvignette
serocalculator 0.5.0
Spell-checking of function documentation and tutorial articles.
Added functions and methods:
load_pop_data()check_pop_data()summary.pop_data()autoplot.pop_data()load_curve_params()
Renamed
graph.decay.curves.by()toautoplot.curve_params()
serocalculator 0.4.0
plot()methods have been renamed toautoplot(), matching general convention forggplot2-based graphics.added visualization of curve parameters
sim.cs()now hasformatargument to specify long or wide format for output.
serocalculator 0.3.2
Fixed bug in passing antigen_isos from est.incidence.by() to est.incidence().
serocalculator 0.3.1
Rolled back required R version from 4.2 to 4.1
serocalculator 0.3.0
- Fixed stability and documentation-clarity issues after initial tester feedback.
serocalculator 0.2.0 (never formally incremented in DESCRIPTION)
- Added new vignettes.
serocalculator 0.1.0
Forking from the seroincidence package and adding Teunis et al 2020 approach.