# How to get fitted values on the response scale for truncated 'asym\_laplace' models

**URL:** <https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649>\
**Category:** brms\
**Created:** [October 30, 2019, 9:36am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649 "2019-10-30T09:36:56Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [October 30, 2019, 9:36am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/1 "2019-10-30T09:36:56Z")

</div>

Dear all,

I’m using a truncated quantile (median) regression (using `asym_laplace`) of the type

```
bf(Y | trunc(lb = 0) ~ 1 + x + (1 | id1) + (1 + x | id2), quantile = 0.5),

```

and would like to get conditional effects via `marginal_effects`. **brms** tells me

`Error: Fitted values on the respone scale not yet implemented for truncated 'asym_laplace' models.`

My question: How difficult and effortful would it be (for me?) to properly implement that functionality and how would I approach this? And if it’s too difficult and effortful, is there a workaround I can use to create the kind of data `marginal_effects` is producing?

Thanks!

- Operating System: macOS 10.14.6
- brms Version: 2.10.0

---

<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 30, 2019, 9:47am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/2 "2019-10-30T09:47:04Z")

</div>

What you need is mainly a formula for the mean of a truncated asymmetric laplace distribution.

---

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [October 30, 2019, 10:53am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/3 "2019-10-30T10:53:18Z")

</div>

I wasn’t able to find a closed-form formula online, but I found a numerical solution based on this paper: [https://www.jstatsoft.org/article/view/v016c02](https://www.jstatsoft.org/article/view/v016c02) (see p. 3)

```
dtrunc <- function(x,
                   spec,
                   a = -Inf,
                   b = Inf,
                   ...)
{
  tt <- rep(0, length(x))
  g <- get(paste("d", spec, sep = ""), mode = "function")
  G <- get(paste("p", spec, sep = ""), mode = "function")
  tt[x >= a & x <= b] <-
    g(x[x >= a & x <= b], ...) / (G(b, ...) - G(a, ...))
  return(tt)
}

extrunc <- function(spec, a = -Inf, b = Inf, ...)
{
  f <- function(x)
    x * dtrunc(x, spec, a = a, b = b, ...)
  return(integrate(f, lower = a, upper = b)$value)
}

```

This then seems to work with **brms** ’s `dasym_laplace` and `pasym_laplace`

```
extrunc("asym_laplace", mu = 1, a = 0) 

```

This approach seems generic enough to support any kind of truncated distributions that **brms** already supports in a non-truncated way.

---

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [October 30, 2019, 12:45pm UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/4 "2019-10-30T12:45:18Z")

</div>

Looking at `vignette("brms_customfamilies")` it seems to me that the quick fix would be to add a function `fitted_trunc_asym_laplace` in `fitted.R`.

```
fitted_trunc_asym_laplace <- function(draws, lb, ub) {
  ###
}

```

Or would it make more sense to replace `dasym_laplace`, `pasym_laplace`, `qasym_laplace`, and `rasym_laplace` in `distributions.R` with versions that can handle truncation? Or is this irrelevant for postprocessing?

---

<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 30, 2019, 5:58pm UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/5 "2019-10-30T17:58:22Z")

</div>

Computing the truncated density is not a problem and brms does that already for arbitary models

The remaining problem is the truncated mean. Of course numerical integration, as done in `extrunc` is always a brute force solution but remember that this needs to be done for each single posterior draws of each single observation, which will be highly inefficient.

---

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [October 31, 2019, 8:54am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/6 "2019-10-31T08:54:33Z")

</div>

OK. Then simply focussing on the use case of me creating a workaround (where I accept the inefficiency of the numerical approach), that is, not a general solution for **brms** , would it be sufficient to implement it in

```
fitted_trunc_asym_laplace <- function(draws, lb, ub) {
  ###
}

```

?

---

<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 31, 2019, 9:00am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/7 "2019-10-31T09:00:46Z")

</div>

Yes it should be sufficient.

---

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [July 23, 2020, 1:33pm UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/8 "2020-07-23T13:33:17Z")

</div>

Dear Paul,

Last October above we discussed about how to implement a brute-force method to calculate the expectation of the median of a truncated asymmetric Laplace distribution.

Based on the functions `dtrunc` and `extrunc` above (taken from p. 3 of [https://www.jstatsoft.org/article/view/v016c02](https://www.jstatsoft.org/article/view/v016c02)), I’ve defined

```
fnc_exp_median_trunc_asym_laplace <- function(mu, sigma, lb, ub) {
  extrunc(
    mu = mu,
    sigma = sigma,
    spec = "asym_laplace",
    a = lb,
    b = ub,
    quantile = .5
  )
}

```

and

```
posterior_epred_trunc_asym_laplace <- function(prep, lb, ub) {
  mapply(fnc_exp_median_trunc_asym_laplace,
         prep$dpars$mu,
         prep$dpars$sigma,
         lb,
         ub)
  
}

```

which computes when I apply it.

But I realize that I do not yet properly handle or understand `prep$dpar$mu` and `prep$dpar$sigma`, since they may differ in length (or rather dimensions) depending on the model fitted.

Is there an another example in [posterior\_epred.R](https://github.com/paul-buerkner/brms/blob/master/R/posterior_epred.R) you can point me to better understand this and possibly even adapt to my use case?

I’m aware that I haven’t yet provided a MRE, so if you think one would be useful here, please let me know.

Thanks!

---

<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:** [July 24, 2020, 11:30am UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/9 "2020-07-24T11:30:11Z")

</div>

Perhaps the code used in [https://github.com/paul-buerkner/brms/blob/master/R/posterior\_predict.R](https://github.com/paul-buerkner/brms/blob/master/R/posterior_predict.R), especially the use of the `get_dpar` function could be helpful in your setting.

---

<div class="post-metadata">

**Author:** ![stefanherzog](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/stefanherzog/32/8762_2.png) [@stefanherzog](https://discourse.mc-stan.org/u/stefanherzog)\
**Post date:** [July 27, 2020, 2:12pm UTC](https://discourse.mc-stan.org/t/how-to-get-fitted-values-on-the-response-scale-for-truncated-asym-laplace-models/11649/10 "2020-07-27T14:12:38Z")

</div>

Thanks a lot for the pointer!
