Package {flexstanr}


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 ORCID iD [aut, cre], Weston Voglesonger [aut]
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:

See Also

Useful links:


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 stan_options().

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 stanfit or a cmdstanr CmdStanMCMC).

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 stanfit or a cmdstanr CmdStanMCMC).

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 stanfit or a cmdstanr CmdStanMCMC).

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 raw_fit.

package

the host package the model belongs to; defaults to the calling package (see fit_model()). Only used by the cmdstanr backend.

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 stanfit or a cmdstanr CmdStanMCMC).

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 "rstan" or "cmdstanr".

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 stan_options() result.

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 draws_array (iteration x chain x variable).

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 draws object for the requested parameters.

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 draws object of the requested generated parameter(s).

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 stanfit or a cmdstanr CmdStanMCMC).

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 stanmodels (rstan) and to locate the .stan source file under its ⁠inst/stan/⁠ (cmdstanr).

dat_stan

the Stan data list.

init

the init list, sized to the chain count.

stan_opts

the validated stan_options() list (carrying a backend element).

drop_pars

character vector of parameter names to exclude from the saved draws, or NULL to keep everything. Honored by rstan; cmdstanr cannot drop parameters and warns if any are requested.

package

name of the host package whose model is being fit. Defaults to the package that called fit_model(), which is correct for the usual case of a host package fitting one of its own models.

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 CmdStanMCMC supplying the parameter draws.

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 "rstan", the rstan::sampling() arguments (iter, cores, seed); for "cmdstanr", the ⁠$sample()⁠ arguments (iter_warmup, iter_sampling, parallel_chains, ...).

chains

A positive integer specifying the number of Markov chains. The default is 4.

backend

which Stan interface to target, one of "rstan" (default) or "cmdstanr". Determines which argument vocabulary is accepted and which sampler fit_model() calls. Selecting "cmdstanr" errors if the cmdstanr package is not installed.

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 DESCRIPTION). Defaults to the working directory.

remote

the GitHub owner/repo used for the interim Remotes entry while flexstanr is pre-CRAN.

on_cran

set TRUE once flexstanr is on CRAN to skip the interim Remotes entry; a plain Imports dependency is then enough.

Value

the host package path, invisibly.

Examples

## Not run: 
# from the root of your Stan package:
flexstanr::use_flexstanr()

## End(Not run)