library(brms)
f <- brms::brmsformula(qsec ~ 0 + Intercept + mpg)9. Linear Models (Posterior)
mean(mtcars$qsec) and \(\sigma\) = 10 * sd(mtcars$qsec)priors <- c(
brms::set_prior("normal(17.85, 17.9)", class = "b", coef = "Intercept"),
brms::set_prior("normal(0, 5)", class = "b", coef = "mpg")
) |>
brms::validate_prior(f, data=mtcars)
priors prior class coef group resp dpar nlpar lb ub source
(flat) b default
normal(17.85, 17.9) b Intercept user
normal(0, 5) b mpg user
student_t(3, 0, 2.5) sigma 0 default
brms::brm() (“Bayesian Regression Model”)brms uses MCMC

brms in the background) also implements variational inference algorithms that sample from an approximation of the posterior, which are faster but less accurate
brm(..., algorithm = "meanfield") (or"fullrank" or "pathfinder")


Family: gaussian
Links: mu = identity
Formula: qsec ~ 0 + Intercept + mpg
Data: mtcars (Number of observations: 32)
Draws: 4 chains, each with iter = 1000; warmup = 500; thin = 1;
total post-warmup draws = 2000
Regression Coefficients:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept 15.31 1.06 13.08 17.40 1.01 723 718
mpg 0.13 0.05 0.02 0.24 1.01 722 663
Further Distributional Parameters:
Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma 1.70 0.23 1.33 2.23 1.00 697 779
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).
effectsize::interpret_ess())effectsize::interpret_rhat())# Fixed Effects
Parameter | Median | 95% CI | pd | Rhat | ESS
------------------------------------------------------------
(Intercept) | 15.31 | [13.08, 17.40] | 100% | 1.008 | 700
mpg | 0.13 | [ 0.02, 0.24] | 99.60% | 1.007 | 689
# sigma Parameters
Parameter | Median | 95% CI | pd | Rhat | ESS
------------------------------------------------------
sigma | 1.68 | [1.33, 2.23] | 100% | 1.005 | 670
parameters (a “general” ESS) is currently different from the one computed by brms, but it doesn’t matter which one you use, they are all estimates anyways and should be relatively close.# Fixed Effects
Parameter | Mean | SD | 89% CI | pd | Rhat | ESS
------------------------------------------------------------------
(Intercept) | 15.31 | 1.06 | [13.64, 16.99] | 100% | 1.008 | 700
mpg | 0.13 | 0.05 | [ 0.04, 0.20] | 99.60% | 1.007 | 689
# sigma Parameters
Parameter | Mean | SD | 89% CI | pd | Rhat | ESS
-----------------------------------------------------------
sigma | 1.70 | 0.23 | [1.37, 2.10] | 100% | 1.005 | 670
# Fixed Effects
Parameter | Median | 95% CI | pd | Rhat | ESS
------------------------------------------------------------
(Intercept) | 15.31 | [13.08, 17.40] | 100% | 1.008 | 700
mpg | 0.13 | [ 0.02, 0.24] | 99.60% | 1.007 | 689
# sigma Parameters
Parameter | Median | 95% CI | pd | Rhat | ESS
------------------------------------------------------
sigma | 1.68 | [1.33, 2.23] | 100% | 1.005 | 670
estimate_* functions from the modelbased package allow us to generate predictions, either for every observation of the dataset, or for a new datasset (e.g., equally spread predictor values to use to plot the regression line)mpg | Predicted | SE | CI | iter_1 | iter_2 | iter_3
--------------------------------------------------------------------
21.00 | 17.95 | 1.75 | [14.42, 21.34] | 17.27 | 16.80 | 16.00
21.00 | 17.91 | 1.74 | [14.60, 21.23] | 21.26 | 16.30 | 17.54
22.80 | 18.24 | 1.75 | [14.64, 21.71] | 16.94 | 15.70 | 17.14
21.40 | 17.97 | 1.73 | [14.53, 21.28] | 18.21 | 17.70 | 21.82
18.70 | 17.67 | 1.72 | [14.42, 21.17] | 13.77 | 14.54 | 20.94
18.10 | 17.59 | 1.72 | [14.21, 20.92] | 19.80 | 19.18 | 17.48
[1] "n-rows = 32 ; n-cols = 256"
Predicted column correspond to the Median of the posterior prediction (the median of the N iterations)keep_iterations argument keeps a subset (or all if TRUE) of individual iterations as additional columnsmpg | Predicted | SE | CI | Residuals | iter_index | iter_group | iter_value
--------------------------------------------------------------------------------------------
21.00 | 17.95 | 1.75 | [14.42, 21.34] | -1.49 | 1 | 1 | 17.27
21.00 | 17.91 | 1.74 | [14.60, 21.23] | -0.89 | 2 | 1 | 21.26
22.80 | 18.24 | 1.75 | [14.64, 21.71] | 0.37 | 3 | 1 | 16.94
21.40 | 17.97 | 1.73 | [14.53, 21.28] | 1.47 | 4 | 1 | 18.21
18.70 | 17.67 | 1.72 | [14.42, 21.17] | -0.65 | 5 | 1 | 13.77
18.10 | 17.59 | 1.72 | [14.21, 20.92] | 2.63 | 6 | 1 | 19.80
[1] "n-rows = 8000 ; n-cols = 9"
geom_line(stat="density") for the lines instead of geom_density() to be able to modify the alpha of the lines (and not the filling)mpg | Predicted | SE | CI | iter_1 | iter_2 | iter_3
--------------------------------------------------------------------
10.40 | 16.62 | 0.57 | [15.44, 17.73] | 16.60 | 16.82 | 17.01
13.01 | 16.95 | 0.46 | [15.96, 17.86] | 16.88 | 17.05 | 17.29
15.62 | 17.28 | 0.37 | [16.54, 18.00] | 17.16 | 17.29 | 17.57
18.23 | 17.60 | 0.31 | [16.98, 18.21] | 17.45 | 17.53 | 17.85
20.84 | 17.93 | 0.31 | [17.32, 18.52] | 17.73 | 17.77 | 18.13
23.46 | 18.26 | 0.36 | [17.57, 18.97] | 18.01 | 18.00 | 18.41
[1] "n-rows = 10 ; n-cols = 255"
reshape these iterations to easily plot all the individual linesmpg | Predicted | SE | CI | iter_index | iter_group | iter_value
--------------------------------------------------------------------------------
10.40 | 16.62 | 0.57 | [15.44, 17.73] | 1 | 1 | 16.60
13.01 | 16.95 | 0.46 | [15.96, 17.86] | 2 | 1 | 16.88
15.62 | 17.28 | 0.37 | [16.54, 18.00] | 3 | 1 | 17.16
18.23 | 17.60 | 0.31 | [16.98, 18.21] | 4 | 1 | 17.45
20.84 | 17.93 | 0.31 | [17.32, 18.52] | 5 | 1 | 17.73
23.46 | 18.26 | 0.36 | [17.57, 18.97] | 6 | 1 | 18.01
[1] "n-rows = 2500 ; n-cols = 8"
geom_point() layer and not in the ggplot() layer, because other layers will different variable names for their y-axis (e.g., Predicted for the predicted line)ggplot(mtcars, aes(x=mpg)) +
geom_point(aes(y=qsec), size=3) +
geom_ribbon(data=pred_wide, aes(ymin=CI_low, ymax=CI_high), fill="darkred", alpha=0.2) +
geom_line(data=pred_wide, aes(y=Predicted), linewidth=2, color="orange") +
geom_line(data=pred_long, aes(y=iter_value, group=iter_group), alpha=0.1)
mpg and qsec
Example of Phrasing
“We fitted a Bayesian linear model (estimated using MCMC sampling with 4 chains of 2000 iterations) to predict qsec with mpg.”
Example of Phrasing
“Mildly informative priors were set for the intercept, \(Normal(M_{qsec}, 10*SD_{qsec})\), and the prior for the effect of mpg was set to \(Normal(0, 5)\).”
Example of Phrasing
Convergence and stability of the Bayesian sampling has been assessed by inspecting the trace plot, as well as with diagnostic indices like the R-hat, which should be below 1.01 (Vehtari et al., 2019), and Effective Sample Size (ESS), which should be greater than 1000 (Burkner, 2017).
The model converged and all parameters had satisfactory ESS and R-hat values.
Example of Phrasing
The model’s explanatory power is substantial (R2 = 0.75, 95% CI [0.65, 0.80]).
Example of Phrasing
We will report the median of the posterior distribution as the point estimate of the parameters, along with the 95% Highest Density Intervals (HDI) as credible intervals (CI) for uncertainty. The probability of the parameter being positive (pd) will be used as an index of existence, with a threshold of 97.5% for “significance” (Makowski et al., 2019). ROPE?
Within this model:
The Intercept (Median = 15.34, 95% CI [13.07, 17.53.12]) has a 100% probability of being positive. [Interpretation]
The effect of mpg (Median = 0.13, 95% CI [0.02, 0.23]) has a 98.55% probability of being positive. [Interpretation]
attitude builtin dataset)?
Normal(0, 0.1))Thank you!
![]()