Brms model object: extracting number of used chains, Bulk and Tail ESS values, and number of divergent transitions

Data and model

library(tidyverse)
library(brms)

df = tibble(y = rnorm(50, 0, 1))

m = brm(data = df, y ~ 1, iter = 200, chains = 4)

m

Model summary

Family: gaussian
Links: mu = identity; sigma = identity
Formula: y ~ 1
Data: df (Number of observations: 50)
Draws: 4 chains, each with iter = 200; warmup = 100; thin = 1;
total post-warmup draws = 400

Population-Level Effects:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 0.18 0.17 -0.19 0.48 1.03 207 126

Family Specific Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 1.12 0.12 0.92 1.38 1.00 461 341

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

How can I extract those 3 numbers in bold and number of divergent transitions with code in R?

You can extract the 3 values from the object returned by summary(m) and the divergent transitions from the model fit (which is stored in m$fit).

First, we get a summary of the model. The object returned by running summary(m) is a list that contains a lot of information about the model, including the values you want to extract. (In fact, when you type m in the console, the output is a printout of some the information returned by summary(m). If you want to see the code for the summary function, type brms:::summary.brmsfit in the console. You can see the code that formats the summary output for printing to the console by typing brms:::print.brmssummary.)

library(tidyverse)
library(brms)

set.seed(15)
df = tibble(y = rnorm(50, 0, 1))

m = brm(data = df, y ~ 1, iter = 200, chains = 4, seed=102, refresh=0)

# Get model summary
ms = summary(m)

ms is a list and you can see what it contains by running str(ms) (I’ve shown the output of this at the end of this answer). After seeing the structure of ms, we can extract the values we want. summary doesn’t return the number of divergent transitions, but we can extract that from the model fit information using the get_num_divergent function from the rstan package. (There might also be extractor functions to get the chains and ESS values, but, if so, I don’t know what they are.)

# Extract the desired values
list(chains = ms$chains,
     bulk.ess = ms$spec_pars$Bulk_ESS,
     tail.ess = ms$spec_pars$Tail_ESS,
     num.divergent = rstan::get_num_divergent(m$fit))
#> $chains
#> [1] 4
#> 
#> $bulk.ess
#> [1] 407.9607
#> 
#> $tail.ess
#> [1] 287.9462
#> 
#> $num.divergent
#> [1] 0
str(ms)
#> List of 16
#>  $ formula  :List of 6
#>   ..$ formula:Class 'formula'  language y ~ 1
#>   .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
#>   .. .. ..- attr(*, "nl")= logi FALSE
#>   .. .. ..- attr(*, "loop")= logi TRUE
#>   ..$ pforms : list()
#>   ..$ pfix   : list()
#>   ..$ resp   : chr "y"
#>   ..$ family :List of 11
#>   .. ..$ family    : chr "gaussian"
#>   .. ..$ link      : chr "identity"
#>   .. ..$ linkfun   :function (mu)  
#>   .. ..$ linkinv   :function (eta)  
#>   .. ..$ dpars     : chr [1:2] "mu" "sigma"
#>   .. ..$ type      : chr "real"
#>   .. ..$ ybounds   : num [1:2] -Inf Inf
#>   .. ..$ closed    : logi [1:2] NA NA
#>   .. ..$ ad        : chr [1:7] "weights" "subset" "se" "cens" ...
#>   .. ..$ normalized: chr [1:5] "_time_hom" "_time_het" "_lagsar" "_errorsar" ...
#>   .. ..$ specials  : chr [1:2] "residuals" "rescor"
#>   .. ..- attr(*, "class")= chr [1:2] "brmsfamily" "family"
#>   ..$ mecor  : logi TRUE
#>   ..- attr(*, "class")= chr [1:2] "brmsformula" "bform"
#>  $ data_name: chr "df"
#>  $ group    : chr(0) 
#>  $ nobs     : int 50
#>  $ ngrps    : NULL
#>  $ autocor  : NULL
#>  $ prior    :Classes 'brmsprior' and 'data.frame':   0 obs. of  9 variables:
#>   ..$ prior : chr(0) 
#>   ..$ class : chr(0) 
#>   ..$ coef  : chr(0) 
#>   ..$ group : chr(0) 
#>   ..$ resp  : chr(0) 
#>   ..$ dpar  : chr(0) 
#>   ..$ nlpar : chr(0) 
#>   ..$ bound : chr(0) 
#>   ..$ source: chr(0) 
#>  $ algorithm: chr "sampling"
#>  $ chains   : num 4
#>  $ iter     : num 200
#>  $ warmup   : num 100
#>  $ thin     : num 1
#>  $ sampler  : chr "sampling(NUTS)"
#>  $ fixed    :'data.frame':   1 obs. of  7 variables:
#>   ..$ Estimate : num 0.268
#>   ..$ Est.Error: num 0.13
#>   ..$ l-95% CI : num 0.0378
#>   ..$ u-95% CI : num 0.533
#>   ..$ Rhat     : num 1.01
#>   ..$ Bulk_ESS : num 256
#>   ..$ Tail_ESS : num 200
#>  $ spec_pars:'data.frame':   1 obs. of  7 variables:
#>   ..$ Estimate : num 0.935
#>   ..$ Est.Error: num 0.0921
#>   ..$ l-95% CI : num 0.777
#>   ..$ u-95% CI : num 1.12
#>   ..$ Rhat     : num 1
#>   ..$ Bulk_ESS : num 408
#>   ..$ Tail_ESS : num 288
#>  $ cor_pars :'data.frame':   0 obs. of  7 variables:
#>   ..$ Estimate : num(0) 
#>   ..$ Est.Error: num(0) 
#>   ..$ l-95% CI : num(0) 
#>   ..$ u-95% CI : num(0) 
#>   ..$ Rhat     : num(0) 
#>   ..$ Bulk_ESS : num(0) 
#>   ..$ Tail_ESS : num(0) 
#>  - attr(*, "class")= chr "brmssummary"
1 Like