Hi, I was trying to fit a non-linear model where the formulat changes over time/space, like linear up to point t and exponential after it. In raw stan I would do something like:
for (x in 1:N)
if (x < t)
y[i] ~ normal(a + b * m, sigma1)
else if (x >= t)
y[i] ~ normal(p + exp(b * r), sigma2)
I couldn’t find an ovious way to implement it in brms
thank you very much
you can try the following. First, define variables xlt = x < t
in your data. Then specify the formula as follows:
bform <- bf(
xlt * (a + b * m) + (1 - xlt) * (p + exp(b * r)),
a + b + p ~ 1,
sigma ~ 0 + xlt
nl = TRUE
)
thanks, but what if “t” is unknown and has to estimated from the data? I was thinking about defining a custum brm response function…maybe it will work
You could try:
bform <- bf(
(x < t) * (a + b * m) + (x >= t) * (p + exp(b * r)),
a + b + p + t ~ 1,
nl = TRUE
)
trying to reproduce but getting a error about x not being recognized as data (I suppose):
a=1; b=0.1; r=0.01; t=20
x=1:100
y=sapply(x, function(i) if(i<t) a + b * i else (b * t) + exp(r * i))
bform ← bf(
y ~ (x < t) * (a + b * x) + (x >= t) * (p * exp(r * x)),
a + b + p + r + t ~ 1,
nl = TRUE
)
fit<-brm(bform, data=data.frame(y=y, x=1:length(y)), prior = c(prior(normal(0, 10), nlpar= a),prior(normal(0, 1), nlpar= b), prior(normal(0, 10), nlpar= p), prior(normal(0, 0.1), nlpar= r), prior(normal(0, 10), nlpar= t)))
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
variable “x” does not exist.
error in ‘model69132a36ad22_file6913163a1d08’ at line 42, column 15
40: for (n in 1:N) {
41: // compute non-linear predictor
42: mu[n] = (x<t) * (nlp_a[n] + nlp_b[n] * C_1[n]) + (x>=t) * (nlp_p[n] * exp(nlp_r[n] * C_1[n]));
^
43: }
Error in stanc(model_code = paste(program, collapse = “\n”), model_name = model_cppname, :
failed to parse Stan model ‘file6913163a1d08’ due to the above error.
Let me check what is going wrong. I will come back to you later on.
The problem should now be fixed in the github version of brms. Here is an example model:
set.seed(1234)
a = 1
b = 10
p = 1
r = 1
t = 0.3
x = seq(0, 1, length.out = 101)
y = ifelse(x < t, a + b * x, p + exp(r * x)) + rnorm(101)
plot(x, y, type = "l")
bform <- bf(
y ~ (x < t) * (a + b * x) + (x >= t) * (p * exp(r * x)),
a + b + p + r + t ~ 1,
nl = TRUE
)
fit <- brm(
bform, data = data.frame(y, x),
prior = c(prior(normal(0, 1), nlpar = a),
prior(normal(0, 10), nlpar = b),
prior(normal(0, 1), nlpar = p),
prior(normal(0, 1), nlpar = r),
prior(uniform(0, 1), nlpar = t, lb = 0, ub = 1)),
chains = 1
)
The model has some convergence problems, but that’s unrelated to the model specification used in brms.
thanks, it works like a charm now,