Lb in brms prior

I want to fit a model where the prior for the parameter mu is bounded from below by 0. This can be done like this in rstan:

"data {
  int N;
  real y[N]; // data
}
parameters {
real<lower=0> mu;
real<lower=0> sigma;
}
model {
  // priors
	mu ~ normal(0,2000);
	sigma ~ normal(0,500);
  // likelihood
  y ~ normal(mu,sigma);
}
generated quantities {
  vector[N] y_sim;
 // posterior predictive
  for(i in 1:N) {
    y_sim[i] = normal_rng(mu,sigma);
  }
}

I generated fake data to fit this model in brms:

set.seed(123)
N <- 500
true_mu <- 400
true_sigma <- 125
y <- rnorm(N, true_mu, true_sigma)

y <- round(y) 
fake_data <- data.frame(y=y)

Then I tried to bound the intercept from below in brms:

priors <- c(set_prior("normal(0, 2000)", 
                      class = "Intercept",lb=0),
            set_prior("normal(0, 500)", 
                      class = "sigma"))

I get the error:

Error: Currently boundaries are only allowed for population-level and autocorrelation parameters.

The intercept is surely a population level parameter? Is this a bug?

It is not a bug. As explained in ?set_prior and ?brmsformula, the intercept is handled separately for reasons of efficiency. If you want the intercept to be included in the rest of the population-level effects, go for y ~ 0 + Intercept + ... and then change the prior accordingly to class = "b".

1 Like

oops. sorry for the dumb question!

Follow-up: Both y ~ 0 + Intercept + ... and y ~ 0 + intercept + ... seem to work (capital and small letter), but ?set_prior mentions the small letter one. Are they the same internal variable?

1 Like

Both do the same, but I would recommend using Intercept because it is the same name as if you were modeling an intercept in the usual way. I will change the documentation accordingly. Perhaps I even deprecate intercept at some point.

3 Likes