Add RStan backend with multivariate observation model (Model B)#191
Draft
Add RStan backend with multivariate observation model (Model B)#191
Conversation
Co-authored-by: Kwan-Jenny <68584166+Kwan-Jenny@users.noreply.github.com> Agent-Logs-Url: https://github.com/ucdavis/serodynamics/sessions/5e1fea32-1feb-43af-968d-c0a34b711ac3
Copilot
AI
changed the title
[WIP] Add RStan backend with multivariate observation model B
Add RStan backend with multivariate observation model (Model B)
Mar 24, 2026
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.
Adds a Stan-based MCMC backend alongside the existing JAGS backend. Model B replaces K independent univariate normal likelihoods with a single K-variate normal per time point, capturing residual correlations across antigen-isotype pairs via an LKJ-prior covariance matrix. JAGS backend is fully unchanged.
New API
New files
inst/stan/model_b.stanfunctions{}block; K-variate normal likelihood; LKJ(2) prior onOmega_eps; half-Cauchy ontau_eps; natural-scale parameters ingenerated quantitiesR/prep_data_stan.Rprep_data()output → Stan list; strips NA padding (replaced with 0, masked byn_obs[i]) and dimension namesR/postprocess_stan_output.Ry0_nat/y1_nat/t1_nat/alpha_nat/shape_natfromgenerated quantities, pivots to longsr_modeltibbleR/run_mod_stan.Rprep_data(..., add_newperson=FALSE); compiles Stan model once per session; attachesOmega_eps,Sigma_eps,fitted_residuals,stan.fitattributesvignettes/articles/stan-multivariate.qmdtests/testthat/test-run_mod_stan.Rrstanis absentModified files
DESCRIPTION:rstanadded toSuggests(optional — package installs without Stan); version bumped to 0.0.0.9048R/serodynamics-package.R: Stan availability note.Rbuildignore: Stan build artifact patterns (.o,.so,.d)NEWS.md,inst/WORDLIST: Updated for new symbols and terminologyDesign notes
rstaninSuggests, notImports— avoids mandatory Stan/C++ toolchain for all users;run_mod_stan()errors informatively if rstan is absentrstantoolspre-compilation — Stan model compiled at first use per session viarstan::stan_model(); eliminatessrc/Makevars infrastructureadd_newperson = FALSE— Stan handles out-of-sample prediction viagenerated quantities, not a dummy row with NA observationsOriginal prompt
This section details on the original issue you should resolve
<issue_title>Add Stan backend with multivariate observation model (Model B)</issue_title>
<issue_description>## Summary
Add an RStan backend to
serodynamicsalongside the existing JAGS backend, starting with Model B: a multivariate observation model that captures residual correlations across antigen-isotype pairs within each time point.Currently,
run_mod()fits each biomarker independently via JAGS (model.jags). Model B replaces the K independent univariate normal likelihoods with a single K-variate normal likelihood per time point, introducing a residual covariance matrix Σ_ε. This is a pathogen-agnostic extension.Motivation
Why Stan? (not extending JAGS)
rstan::stan_model()compiles Stan → C++ transparently. Users just needrstaninstalled.Package integration strategy
Use
rstantoolsto properly integrate Stan into the R package:This creates
src/directory with Makevars,inst/stan/for .stan files, and configures the package to pre-compile Stan models at install time. Users then get fast model access without runtime compilation.Key:
rstangoes inImports(notSuggests) if we userstantools, because the compiled Stan models are part of the package binary. But we keep the JAGS backend fully functional —run_mod()is unchanged.Scope of changes
New files
inst/stan/model_b.stanR/run_mod_stan.Rrun_mod()R/prep_data_stan.Rprepped_jags_data→ Stan-ready listR/postprocess_stan_output.Rstanfit→sr_modelclass tibblevignettes/articles/stan-multivariate.qmdtests/testthat/test-run_mod_stan.RFiles to modify
DESCRIPTIONrstan,StanHeaders,rstantoolsto Imports; addSystemRequirements: GNU makeR/serodynamics-package.R.RbuildignoreFiles NOT modified
run_mod(),prep_data(),prep_priors(),calc_fit_mod(),model.jags— all stay exactly as is. Full backward compatibility.API design:
run_mod_stan()Mirrors the existing
run_mod()interface:Input: Same
datafromas_case_data()— no new data format needed.Output: Same
sr_modeltibble with columns:Iteration,Chain,Parameter,Iso_type,Stratification,Subject,value. All existing plot/su...⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.