| Title: | Portable Backend Layer for 'Stan' Models |
| Version: | 0.1.0 |
| Description: | Gives a 'Stan'-based R package one interface for fitting its models through either 'rstan' or (optionally) 'cmdstanr'. Collects and validates sampler options, guarding against mixing one backend's argument vocabulary into the other, dispatches the fit to the chosen backend, and exposes backend-agnostic accessors for reading posterior draws, extracting parameters, and running generated quantities. The host package supplies its own compiled models; flexstanr resolves them from the calling package at run time, so the same code works whichever backend is installed. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Language: | en-US |
| Depends: | R (≥ 4.1.0) |
| Imports: | methods, rstan (≥ 2.18.1), tools |
| Suggests: | cmdstanr, desc, knitr, posterior, rmarkdown, spelling, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Additional_repositories: | https://stan-dev.r-universe.dev |
| Config/testthat/edition: | 3 |
| URL: | https://accidda.github.io/flexstanr/, https://github.com/ACCIDDA/flexstanr |
| BugReports: | https://github.com/ACCIDDA/flexstanr/issues |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-07-09 14:03:27 UTC; runner |
| Author: | Carl Pearson |
| Maintainer: | Carl Pearson <carl.ab.pearson@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-17 14:20:08 UTC |
flexstanr: Portable Backend Layer for 'Stan' Models
Description
Gives a 'Stan'-based R package one interface for fitting its models through either 'rstan' or (optionally) 'cmdstanr'. Collects and validates sampler options, guarding against mixing one backend's argument vocabulary into the other, dispatches the fit to the chosen backend, and exposes backend-agnostic accessors for reading posterior draws, extracting parameters, and running generated quantities. The host package supplies its own compiled models; flexstanr resolves them from the calling package at run time, so the same code works whichever backend is installed.
Author(s)
Maintainer: Carl Pearson carl.ab.pearson@gmail.com (ORCID)
Authors:
Carl Pearson carl.ab.pearson@gmail.com (ORCID)
Weston Voglesonger westonvogle@gmail.com
See Also
Useful links:
Report bugs at https://github.com/ACCIDDA/flexstanr/issues
Assert a backend name is valid and its package is installed
Description
Validates backend against the known choices (so it also subsumes
match.arg()) and, for the optional cmdstanr backend, that its package is
installed. rstan is always available (a hard dependency); cmdstanr is
optional, so selecting it without the package installed fails early here
rather than deep inside the fit. Returns the validated backend invisibly.
Usage
assert_backend_available(backend)
Arguments
backend |
the backend to validate. |
Value
the validated backend string, invisibly.
Assert that no foreign-backend argument vocabulary was used
Description
Errors if any argument name belongs to the other backend's vocabulary, with a "did you mean" hint. On success returns the argument names invisibly.
Usage
assert_backend_vocab(arg_names, backend)
Arguments
arg_names |
names of the arguments supplied to |
backend |
the backend the options are being built for. |
Value
arg_names, invisibly.
Assert a value is a positive integer (vector)
Description
Errors on invalid input (non-numeric, empty, NA, non-integer, or
non-positive values); otherwise returns the value coerced to integer. Used to
validate count-like arguments.
Usage
assert_positive_int(val, name)
Arguments
val |
the value to validate. |
name |
the argument name, used in error messages. |
Value
val, coerced to a positive integer (vector).
Posterior draws of a fit as an iterations x chains x parameters array
Description
Posterior draws of a fit as an iterations x chains x parameters array
Usage
backend_draws_array(raw_fit)
Arguments
raw_fit |
a backend-native fit object (an rstan |
Value
a 3-D array, dimensions iterations x chains x parameters.
Examples
## Not run:
draws <- backend_draws_array(fit)
dim(draws) # iterations x chains x parameters
## End(Not run)
Extract named parameters from a fit as a list of arrays
Description
Matches the shape returned by rstan::extract().
Usage
backend_extract(raw_fit, pars, ...)
Arguments
raw_fit |
a backend-native fit object (an rstan |
pars |
character vector of parameter names to extract. |
... |
forwarded to the backend's extractor. |
Value
a named list of draw arrays, one per parameter.
Examples
## Not run:
post <- backend_extract(fit, pars = c("beta", "sigma"))
## End(Not run)
Run generated quantities against a fit and return a parameter matrix
Description
Run generated quantities against a fit and return a parameter matrix
Usage
backend_generate_quantities(
raw_fit,
data,
draws_mat,
pars,
model_name = NULL,
package = NULL
)
Arguments
raw_fit |
a backend-native fit object (an rstan |
data |
the Stan data list for the generated-quantities run. |
draws_mat |
a draws matrix (rows = draws, columns = parameters). Used by the rstan backend; the cmdstanr backend runs generated quantities against the fit's own draws and ignores this argument. |
pars |
name of the generated parameter to return. |
model_name |
name of the model whose generated-quantities block to run.
Required by the cmdstanr backend, which recompiles the model to run it;
ignored by rstan, which reuses the model carried on |
package |
the host package the model belongs to; defaults to the calling
package (see |
Value
a matrix of the requested generated parameter (rows = draws).
Examples
## Not run:
gen <- backend_generate_quantities(fit, data = data_list,
draws_mat = as.matrix(fit), pars = "y_rep")
## End(Not run)
Does a fit object carry usable posterior draws?
Description
Detect the degenerate "no draws" case after a fit, so a caller
can fail loudly instead of returning an empty fit. This is backend-aware:
rstan returns a mode-2 stanfit with an empty @sim when the sampler fails
to initialize (rather than erroring), while cmdstanr exposes its draws through
$draws(). Unrecognized objects (e.g. test mocks) are treated as having draws
so they pass through untouched.
Usage
backend_has_draws(raw_fit)
Arguments
raw_fit |
a backend-native fit object (an rstan |
Value
logical; TRUE if the fit carries usable draws.
Examples
# Unrecognized objects are treated as carrying draws (pass-through).
backend_has_draws(list())
Positive-integer count arguments native to a backend's sampler
Description
Positive-integer count arguments native to a backend's sampler
Usage
backend_int_args(backend)
Arguments
backend |
one of |
Value
a character vector of argument names that must be positive integers.
Name of the package that called into flexstanr
Description
flexstanr resolves a host's compiled model from the host's own namespace, so
it must know which package called it. This walks out to the top-level
environment of the calling frame and returns its package name. Returns NULL
when called from the global environment or another context without a package
(e.g. interactively), so callers can fail with an actionable message.
Usage
caller_package(env = parent.frame())
Arguments
env |
the environment to resolve from; defaults to the caller's frame. |
Value
the calling package's name, or NULL if there is none.
Check whether per-chain threading is enabled for the active backend
Description
cmdstanr configures threading through the threads_per_chain sampler
argument; rstan reads the STAN_NUM_THREADS environment variable at run
time (-1 meaning all available cores). Only the run-time configuration is
checked, not whether the model was compiled with threading support. The fit
functions do not consult this themselves: a host package running a threaded
model calls it to warn when the user has not made threads available.
Usage
check_threaded(stan_opts)
Arguments
stan_opts |
a |
Value
logical; TRUE if per-chain threading is enabled, otherwise FALSE.
Coerce a cmdstanr draws array to a plain iterations x chains x parameters array
Description
Coerce a cmdstanr draws array to a plain iterations x chains x parameters array
Usage
cmdstanr_draws_array(draws)
Arguments
draws |
a posterior |
Value
a base 3-D array, matching as.array() on an rstan stanfit.
Reshape cmdstanr draws into rstan::extract()'s list-of-arrays
Description
Groups the flat, indexed variables (theta[1], theta[2], ...) back into one
array per parameter with draws merged across chains, matching the shape
rstan::extract() returns: a bare vector for a scalar parameter, an
S x dims array otherwise. Unlike rstan's default the draws are not randomly
permuted; they keep iteration-chain order, which is immaterial for the
exchangeable-sample uses these draws are put to.
Usage
cmdstanr_extract(draws, pars)
Arguments
draws |
a posterior |
pars |
the parameter base names to extract. |
Value
a named list of draw arrays, one per parameter.
Coerce cmdstanr generated-quantities draws to a draws x parameters matrix
Description
Coerce cmdstanr generated-quantities draws to a draws x parameters matrix
Usage
cmdstanr_gq_matrix(gq_draws)
Arguments
gq_draws |
a posterior |
Value
a base matrix (rows = draws), matching the rstan path's
as.matrix(gqs(...), pars = ...).
Identify the backend that produced a fit object
Description
Identify the backend that produced a fit object
Usage
fit_backend(raw_fit)
Arguments
raw_fit |
a backend-native fit object (an rstan |
Value
"rstan" or "cmdstanr".
Fit a Stan model through the chosen backend
Description
Dispatches a fit to the backend recorded on stan_opts (from
stan_options()). The compiled model is resolved by model_name from the
calling package: for "rstan", package::stanmodels[[model_name]]; for
"cmdstanr", inst/stan/<model_name>.stan under package. The calling
package is detected automatically and can be overridden with package.
Usage
fit_model(
model_name,
dat_stan,
init,
stan_opts,
drop_pars = NULL,
package = NULL
)
Arguments
model_name |
name of the Stan model; used to look up the compiled model
in the calling package's |
dat_stan |
the Stan data list. |
init |
the init list, sized to the chain count. |
stan_opts |
the validated |
drop_pars |
character vector of parameter names to exclude from the
saved draws, or |
package |
name of the host package whose model is being fit. Defaults to
the package that called |
Value
the backend's fit object (a stanfit or CmdStanMCMC).
Examples
## Not run:
# From inside a host package that ships a compiled `coverage` model:
opts <- stan_options(chains = 2, iter = 500, seed = 1)
fit <- fit_model("coverage", dat_stan = data_list, init = init_list,
stan_opts = opts)
## End(Not run)
Resolve a host package's compiled rstan model
Description
Looks up model_name in the calling package's stanmodels object (the
rstantools-generated registry of compiled models). This replaces the
ambient stanmodels[[model_name]] lookup that worked only when this code was
vendored into the host: as an imported package, flexstanr must reach into the
host's namespace explicitly.
Usage
get_stanmodel(package, model_name)
Arguments
package |
the host package name. |
model_name |
the model to resolve. |
Value
the compiled stanmodel object.
Run cmdstanr generated quantities for a host model
Description
Resolves the host's .stan model the same way fit_model() does, compiles it
into a writable cache, and runs its generated-quantities block against the
fitted draws.
Usage
run_cmdstanr_gq(model_name, package, raw_fit, data)
Arguments
model_name |
the model to run. |
package |
the host package the model belongs to. |
raw_fit |
the fitted |
data |
the Stan data list for the generated-quantities run. |
Value
a CmdStanGQ object.
Stan Sampler Options
Description
Collects and validates sampler arguments for the chosen backend, forwarding
them verbatim so calls feel native to that backend. Use the backend's own
argument names; mixing one backend's vocabulary into the other errors with a
hint. The model object is supplied separately (via fit_model()), while
data and init are constructed internally, so none of these may be set
here. chains defaults to 4 so downstream code can always size per-chain
structures from it.
Usage
stan_options(..., chains = 4L, backend = "rstan")
Arguments
... |
sampler arguments forwarded verbatim to the chosen backend's
sampler. Use the backend's own names: for |
chains |
A positive integer specifying the number of Markov chains. The default is 4. |
backend |
which Stan interface to target, one of |
Value
a named list of validated sampler arguments, carrying a backend
element recording the backend it was built for
Examples
stan_options()
stan_options(chains = 2, iter = 500)
if (requireNamespace("cmdstanr", quietly = TRUE)) {
stan_options(backend = "cmdstanr", parallel_chains = 4, iter_warmup = 500)
}
Wire flexstanr into a host package
Description
A one-time setup helper, in the spirit of usethis's use_* functions, that
declares flexstanr as a dependency of the host package you run it from. It
adds flexstanr (and rstan, the default backend) to the host's Imports and,
until flexstanr is on CRAN, an interim Remotes entry so remotes / pak
can install it from GitHub.
No further wiring is needed: the host calls fit_model() and the backend_*
accessors directly, and flexstanr resolves the host's own compiled models
automatically from the calling package.
Usage
use_flexstanr(path = ".", remote = "ACCIDDA/flexstanr", on_cran = FALSE)
Arguments
path |
path to the host package's root (the directory containing its
|
remote |
the GitHub |
on_cran |
set |
Value
the host package path, invisibly.
Examples
## Not run:
# from the root of your Stan package:
flexstanr::use_flexstanr()
## End(Not run)