Varying intercepts with single level group effect

Hello,

(I would also interested in how to solve this in Stan, particularly if there is a good example available but ideally I want to do this with brms)

I am working on something where a continuous response is related to a continuous predictor across different locations. I do not want to pool information across locations but I do want to let the intercept vary across blocks (sub-groups) within locations. However one location does not have sub-groups. If I was modelling this for each location separately, I would do something like y ~ 1 + x + (1|b) and drop the varying intercept term for the location without subgroups. But when modelling them together, location B gets varying intercepts across a single level of b, which inflates uncertainty.

(I was also surprised to see that y ~ 1 + x + (1|b) and y ~ 1 + x yield different estimates, at least in terms of uncertainty, when modelling that location alone but that’s probably just me not fully understanding what varying intercepts does under the hood; I was thinking of it as averaging over the levels of the group predictor, with partial pooling, which in this case would be like averaging over one)

Anyway, is there a way to “switch off” varying intercepts for those levels of a higher level predictor that do not have sub-groups?

library(tidyverse)

d = data.frame(x = rnorm(500),
               z = rep(letters[1:5], each = 100),
               b = rep(c("1","2"), 50)) %>% 
  mutate(b = str_c(z, b))

d$y = 5 + 3*d$x + rnorm(500)

library(brms)
m = brm(
  bf(
    y ~ 1 + x*z + (1|gr(b, by = z))
  ),
  backend = "cmdstanr",
  chains = 4,
  iter = 4000,
  warmup = 2000,
  cores = 4,
  seed = 42,
  data = d %>% filter(!(z == "b" & b == "b2"))
)
summary(m)

conditional_effects(m, effects ="x:z") %>% 
  plot() %>% 
  .[[1]] +
  facet_wrap(~z)

It just means that each element of b gets its own intercept. For instance, if I do 1 | age and there are five age groups, then each age gets its own intercept. I’m not sure if brms uses a sum-to-zero or a pin age[1] == 0 to identify.

What’s going to happen here with the global intercept is that the 1 | b terms will pick up differences among the groups indicated by b in intercept.

My confusion is about what happens if you do 1 | age when you only have only one age group. I would expect in that case the model to be equivalent to one without the 1 | age but it is not. In my example, we have four locations with two groups each and one (panel b in the figure) with only one group.

I’m not sure. It should just drop that out, but I can imagine it getting confused and producing two intercepts that are collinear and running into all kinds of problems. I suggest just not doing 1 | age when there is only one age :-).