# Varying formula over time/space

**URL:** <https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904>\
**Category:** brms\
**Created:** [October 6, 2018, 2:58pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904 "2018-10-06T14:58:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![blackrabite](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/blackrabite/32/8887_2.png) [@blackrabite](https://discourse.mc-stan.org/u/blackrabite)\
**Post date:** [October 6, 2018, 2:58pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/1 "2018-10-06T14:58:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![paul.buerkner](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/paul.buerkner/32/3303_2.png) [@paul.buerkner](https://discourse.mc-stan.org/u/paul.buerkner)\
**Post date:** [October 6, 2018, 3:45pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/2 "2018-10-06T15:45:56Z")

</div>

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
)

```

---

<div class="post-metadata">

**Author:** ![blackrabite](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/blackrabite/32/8887_2.png) [@blackrabite](https://discourse.mc-stan.org/u/blackrabite)\
**Post date:** [October 6, 2018, 3:52pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/3 "2018-10-06T15:52:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![paul.buerkner](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/paul.buerkner/32/3303_2.png) [@paul.buerkner](https://discourse.mc-stan.org/u/paul.buerkner)\
**Post date:** [October 6, 2018, 3:54pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/4 "2018-10-06T15:54:28Z")

</div>

You could try:

```
bform <- bf(
  (x < t) * (a + b * m) + (x >= t) * (p + exp(b * r)),
  a + b + p + t ~ 1,
  nl = TRUE
)

```

---

<div class="post-metadata">

**Author:** ![blackrabite](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/blackrabite/32/8887_2.png) [@blackrabite](https://discourse.mc-stan.org/u/blackrabite)\
**Post date:** [October 6, 2018, 4:35pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/5 "2018-10-06T16:35:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![paul.buerkner](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/paul.buerkner/32/3303_2.png) [@paul.buerkner](https://discourse.mc-stan.org/u/paul.buerkner)\
**Post date:** [October 6, 2018, 4:37pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/6 "2018-10-06T16:37:48Z")

</div>

Let me check what is going wrong. I will come back to you later on.

---

<div class="post-metadata">

**Author:** ![paul.buerkner](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/paul.buerkner/32/3303_2.png) [@paul.buerkner](https://discourse.mc-stan.org/u/paul.buerkner)\
**Post date:** [October 6, 2018, 8:16pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/7 "2018-10-06T20:16:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![blackrabite](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/blackrabite/32/8887_2.png) [@blackrabite](https://discourse.mc-stan.org/u/blackrabite)\
**Post date:** [October 6, 2018, 8:41pm UTC](https://discourse.mc-stan.org/t/varying-formula-over-time-space/5904/8 "2018-10-06T20:41:32Z")

</div>

thanks, it works like a charm now,
