This vignette demonstrates how to
access most of data stored in a stanfit object. A stanfit object (an
object of class "stanfit"
) contains the output derived from
fitting a Stan model using Markov chain Monte Carlo or one of Stan’s
variational approximations (meanfield or full-rank). Throughout the
document we’ll use the stanfit object obtained from fitting the Eight
Schools example model:
[1] "stanfit"
attr(,"package")
[1] "rstan"
There are several functions that can be used to access the draws from
the posterior distribution stored in a stanfit object. These are
extract
, as.matrix
,
as.data.frame
, and as.array
, each of which
returns the draws in a different format.
The extract
function (with its default arguments)
returns a list with named components corresponding to the model
parameters.
[1] "mu" "tau" "eta" "theta" "lp__"
In this model the parameters mu
and tau
are
scalars and theta
is a vector with eight elements. This
means that the draws for mu
and tau
will be
vectors (with length equal to the number of post-warmup iterations times
the number of chains) and the draws for theta
will be a
matrix, with each column corresponding to one of the eight
components:
[1] 20.836497 12.060795 10.175120 9.520696 6.096034 7.859518
[1] 14.905177 7.899398 26.940079 2.048036 19.108677 4.378995
iterations [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 28.726974 9.439800 3.888388 15.339154 7.7346833 17.664277
[2,] 4.700456 16.206078 7.751389 10.825984 -0.9480708 5.075414
[3,] 24.922388 11.790502 6.009507 11.390416 6.3207077 7.306853
[4,] 10.815966 9.828443 9.355722 9.044572 9.7469111 7.148323
[5,] 17.501890 2.933129 -16.807166 -2.578389 -2.4783181 1.142213
[6,] 5.616234 2.031239 7.773633 8.855767 8.5948272 8.086332
iterations [,7] [,8]
[1,] 24.957668 14.090334
[2,] 13.347809 15.401941
[3,] 15.622450 31.626042
[4,] 11.053766 9.552939
[5,] 8.771172 15.201472
[6,] 13.032274 0.103350
The as.matrix
, as.data.frame
, and
as.array
functions can also be used to retrieve the
posterior draws from a stanfit object:
[1] "mu" "tau" "eta[1]" "eta[2]" "eta[3]" "eta[4]"
[7] "eta[5]" "eta[6]" "eta[7]" "eta[8]" "theta[1]" "theta[2]"
[13] "theta[3]" "theta[4]" "theta[5]" "theta[6]" "theta[7]" "theta[8]"
[19] "lp__"
[1] "mu" "tau" "eta[1]" "eta[2]" "eta[3]" "eta[4]"
[7] "eta[5]" "eta[6]" "eta[7]" "eta[8]" "theta[1]" "theta[2]"
[13] "theta[3]" "theta[4]" "theta[5]" "theta[6]" "theta[7]" "theta[8]"
[19] "lp__"
$iterations
NULL
$chains
[1] "chain:1" "chain:2" "chain:3" "chain:4"
$parameters
[1] "mu" "tau" "eta[1]" "eta[2]" "eta[3]" "eta[4]"
[7] "eta[5]" "eta[6]" "eta[7]" "eta[8]" "theta[1]" "theta[2]"
[13] "theta[3]" "theta[4]" "theta[5]" "theta[6]" "theta[7]" "theta[8]"
[19] "lp__"
The as.matrix
and as.data.frame
methods
essentially return the same thing except in matrix and data frame form,
respectively. The as.array
method returns the draws from
each chain separately and so has an additional dimension:
[1] 4000 19
[1] 4000 19
[1] 1000 4 19
By default all of the functions for retrieving the posterior draws
return the draws for all parameters (and generated quantities).
The optional argument pars
(a character vector) can be used
if only a subset of the parameters is desired, for example:
parameters
iterations mu theta[1]
[1,] 8.725579 10.215258
[2,] 9.226547 11.440963
[3,] 15.899183 33.442211
[4,] 3.241677 3.780407
[5,] 7.509794 3.163952
[6,] 6.485575 5.913785
Summary statistics are obtained using the summary
function. The object returned is a list with two components:
[1] "summary" "c_summary"
In fit_summary$summary
all chains are merged whereas
fit_summary$c_summary
contains summaries for each chain
individually. Typically we want the summary for all chains merged, which
is what we’ll focus on here.
The summary is a matrix with rows corresponding to parameters and
columns to the various summary quantities. These include the posterior
mean, the posterior standard deviation, and various quantiles computed
from the draws. The probs
argument can be used to specify
which quantiles to compute and pars
can be used to specify
a subset of parameters to include in the summary.
For models fit using MCMC, also included in the summary are the Monte
Carlo standard error (se_mean
), the effective sample size
(n_eff
), and the R-hat statistic (Rhat
).
mean se_mean sd 2.5% 25%
mu 8.03134880 0.12101259 5.1677701 -2.0380719 4.6592144
tau 6.59041549 0.14568776 5.6008007 0.2773337 2.4968590
eta[1] 0.38208289 0.01499024 0.9451615 -1.4660826 -0.2432909
eta[2] -0.01569986 0.01415572 0.8978636 -1.8122466 -0.6076035
eta[3] -0.19538335 0.01485024 0.9273103 -2.0419114 -0.8001488
eta[4] -0.05392870 0.01381316 0.8822209 -1.7583078 -0.6355066
eta[5] -0.33887850 0.01409636 0.8530216 -1.9339251 -0.9058867
eta[6] -0.20933652 0.01316414 0.8898184 -1.9389494 -0.8007213
eta[7] 0.33777380 0.01514154 0.8590626 -1.4159776 -0.2037721
eta[8] 0.07570978 0.01498566 0.9437228 -1.7859882 -0.5473077
theta[1] 11.48411741 0.15569415 8.4652775 -2.1680738 6.0199819
theta[2] 7.82245427 0.08511068 6.3415271 -5.0159470 3.8104565
theta[3] 6.36484448 0.12193545 7.6663689 -10.4674407 2.1200451
theta[4] 7.56946935 0.09640997 6.4548621 -5.5564139 3.6792036
theta[5] 5.30928037 0.10785842 6.3324894 -8.5331457 1.5769709
theta[6] 6.22346676 0.09747826 6.5826572 -8.2492415 2.4799313
theta[7] 10.71783910 0.11940361 6.6978000 -1.2805184 6.4235510
theta[8] 8.65574392 0.13520688 8.0679915 -7.2725471 4.0054656
lp__ -39.50903872 0.07598791 2.6496622 -45.5537291 -41.1068886
50% 75% 97.5% n_eff Rhat
mu 8.054478e+00 11.2207326 18.678096 1823.666 1.0000454
tau 5.225528e+00 9.1012987 20.652894 1477.931 1.0037510
eta[1] 3.865713e-01 1.0122973 2.219547 3975.527 0.9998628
eta[2] -6.638748e-04 0.5795009 1.807664 4023.060 0.9992227
eta[3] -1.913628e-01 0.4101593 1.656482 3899.269 1.0004837
eta[4] -7.720218e-02 0.5137489 1.764653 4079.137 0.9997942
eta[5] -3.480289e-01 0.1983097 1.437134 3661.898 0.9995048
eta[6] -2.074909e-01 0.3651111 1.550091 4568.962 0.9993792
eta[7] 3.365219e-01 0.8920357 2.037641 3218.913 1.0015100
eta[8] 7.685418e-02 0.7046980 1.941707 3965.860 0.9999269
theta[1] 1.023291e+01 15.5175399 32.364864 2956.227 0.9997673
theta[2] 7.907364e+00 11.6695588 20.575500 5551.619 0.9996755
theta[3] 6.779341e+00 10.9805161 21.030802 3952.933 0.9994922
theta[4] 7.703315e+00 11.5038791 20.591890 4482.601 0.9999101
theta[5] 5.837589e+00 9.5163070 16.501357 3446.996 1.0012477
theta[6] 6.649826e+00 10.4868048 18.648563 4560.232 0.9999849
theta[7] 1.023562e+01 14.4673170 25.607596 3146.512 1.0030312
theta[8] 8.427871e+00 12.9113150 26.403308 3560.683 0.9999748
lp__ -3.925657e+01 -37.6681354 -35.083758 1215.884 1.0023318
If, for example, we wanted the only quantiles included to be 10% and
90%, and for only the parameters included to be mu
and
tau
, we would specify that like this:
mu_tau_summary <- summary(fit, pars = c("mu", "tau"), probs = c(0.1, 0.9))$summary
print(mu_tau_summary)
mean se_mean sd 10% 90% n_eff Rhat
mu 8.031349 0.1210126 5.167770 1.705679 14.28522 1823.666 1.000045
tau 6.590415 0.1456878 5.600801 1.021370 13.81310 1477.931 1.003751
Since mu_tau_summary
is a matrix we can pull out columns
using their names:
10% 90%
mu 1.705679 14.28522
tau 1.021370 13.81310
For models fit using MCMC the stanfit object will also contain the
values of parameters used for the sampler. The
get_sampler_params
function can be used to access this
information.
The object returned by get_sampler_params
is a list with
one component (a matrix) per chain. Each of the matrices has number of
columns corresponding to the number of sampler parameters and the column
names provide the parameter names. The optional argument inc_warmup
(defaulting to TRUE
) indicates whether to include the
warmup period.
sampler_params <- get_sampler_params(fit, inc_warmup = FALSE)
sampler_params_chain1 <- sampler_params[[1]]
colnames(sampler_params_chain1)
[1] "accept_stat__" "stepsize__" "treedepth__" "n_leapfrog__"
[5] "divergent__" "energy__"
To do things like calculate the average value of
accept_stat__
for each chain (or the maximum value of
treedepth__
for each chain if using the NUTS algorithm,
etc.) the sapply
function is useful as it will apply the
same function to each component of sampler_params
:
mean_accept_stat_by_chain <- sapply(sampler_params, function(x) mean(x[, "accept_stat__"]))
print(mean_accept_stat_by_chain)
[1] 0.8894886 0.9646873 0.8557073 0.8995515
max_treedepth_by_chain <- sapply(sampler_params, function(x) max(x[, "treedepth__"]))
print(max_treedepth_by_chain)
[1] 5 4 4 4
The Stan program itself is also stored in the stanfit object and can
be accessed using get_stancode
:
The object code
is a single string and is not very
intelligible when printed:
[1] "data {\n int<lower=0> J; // number of schools\n real y[J]; // estimated treatment effects\n real<lower=0> sigma[J]; // s.e. of effect estimates\n}\nparameters {\n real mu;\n real<lower=0> tau;\n vector[J] eta;\n}\ntransformed parameters {\n vector[J] theta;\n theta = mu + tau * eta;\n}\nmodel {\n target += normal_lpdf(eta | 0, 1);\n target += normal_lpdf(y | theta, sigma);\n}"
attr(,"model_name2")
[1] "schools"
A readable version can be printed using cat
:
data {
int<lower=0> J; // number of schools
real y[J]; // estimated treatment effects
real<lower=0> sigma[J]; // s.e. of effect estimates
}
parameters {
real mu;
real<lower=0> tau;
vector[J] eta;
}
transformed parameters {
vector[J] theta;
theta = mu + tau * eta;
}
model {
target += normal_lpdf(eta | 0, 1);
target += normal_lpdf(y | theta, sigma);
}
The get_inits
function returns initial values as a list
with one component per chain. Each component is itself a (named) list
containing the initial values for each parameter for the corresponding
chain:
$mu
[1] -1.931844
$tau
[1] 0.3738421
$eta
[1] 0.992145893 -0.571812941 1.505868780 0.752517743 0.009724263
[6] 1.950971272 -1.890238232 0.897926154
$theta
[1] -1.560938 -2.145612 -1.368887 -1.650521 -1.928209 -1.202489 -2.638495
[8] -1.596161
The get_seed
function returns the (P)RNG seed as an
integer:
[1] 1665972213