# Drop draws below a threshold rather than setting a lower bound on a prior for nu

**URL:** <https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476>\
**Category:** Modeling\
**Tags:** fitting-issues, specification\
**Created:** [October 8, 2025, 8:49pm UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476 "2025-10-08T20:49:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Solomon](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/solomon/32/2495_2.png) [@Solomon](https://discourse.mc-stan.org/u/Solomon)\
**Post date:** [October 8, 2025, 8:49pm UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/1 "2025-10-08T20:49:19Z")

</div>

Say I have some fat-tail Student-t data, I fit a model using the Student-t likelihood, and the bulk of the \nu posterior is sitting well in the low-end of the range. Further say I want to use those posterior draws from \nu and \sigma to compute a posterior for the standard deviation using the formula \sigma \sqrt{\nu / (\nu - 2)} for \nu \> 2 (see [Student's t-distribution - Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-distribution)). For the prior on \nu, I use the brms default \operatorname{gamma}(2, 0.1), but in two different ways:

- set the lower bound at 2 (`lb = 2`), or
- set the lower bound at 0, but just drop all posterior draws for which \nu \le 2.

Are both methods equally valid?

Here’s a quick example. I’m using brms here, but this is a more general Stan question.

```no-highlight
# Load packages
library(tidyverse)
library(brms)
library(ggdist)

# Simulate fat-tail t data
set.seed(1)

student_data <- data.frame(y = rstudent_t(n = 100, df = 3))

# Fit the two versions of the model
fit_nu_lb_0 <- brm(
  data = student_data,
  family = student,
  y ~ 1,
  prior = prior(gamma(2, 0.1), class = nu, lb = 0),
  cores = 1, seed = 1, warmup = 500, iter = 5500)

fit_nu_lb_2 <- brm(
  data = student_data,
  family = student,
  y ~ 1,
  # Notice the different `lb` setting
  prior = prior(gamma(2, 0.1), class = nu, lb = 2),
  cores = 1, seed = 1, warmup = 500, iter = 5500)

# Extract and save the posterior draws
draws_lb_0 <- as_draws_df(fit_nu_lb_0)
draws_lb_2 <- as_draws_df(fit_nu_lb_2)

```

For the model that used `lb = 0`, there were indeed several draws for \nu below the 2 threshold.

```no-highlight
draws_lb_0 |> 
  summarize(n_below_2_lb = sum(nu <= 2),
            percent_below_2_lb = 100 * mean(nu <= 2))

draws_lb_0 |> 
  ggplot(aes(x = nu, fill = nu > 2, group = nu > 2)) +
  geom_histogram(breaks = seq(from = 0, to = 60, by = 0.1)) +
  scale_x_continuous(expression(nu), breaks = 0:5 * 2) +
  scale_y_continuous(NULL, breaks = NULL) +
  coord_cartesian(xlim = c(0, 10))

```

```no-highlight
# A tibble: 1 × 2
  n_below_2_lb percent_below_2_lb
         <int> <dbl>
1 617 3.08

```

 ![Screenshot 2025-10-08 at 3.43.38 PM](https://canada1.discourse-cdn.com/flex030/uploads/mc_stan/original/3X/5/a/5aec5f36f8d820971181a70a4e1fda88f4b827d3.png)

However, if one dropped all those draws for which \nu \le 2 from the `fit_lb_0` version of the model, the posteriors for \nu look very similar for both versions of the model.

```no-highlight
bind_rows(draws_lb_0, draws_lb_2) |> 
  mutate(lb = rep(c("lb = 0", "lb = 2"), each = n() / 2)) |> 
  # Drop those unwanted draws
  filter(nu > 2) |> 
  
  ggplot(aes(x = nu, y = lb)) +
  stat_histinterval(breaks = seq(from = 0, to = 60, by = 0.1)) +
  scale_x_continuous(expression(nu), breaks = 0:5 * 2) +
  scale_y_discrete(NULL, expand = expansion(mult = 0.1)) +
  coord_cartesian(xlim = c(1, 10))

```

 ![Screenshot 2025-10-08 at 3.45.16 PM](https://canada1.discourse-cdn.com/flex030/uploads/mc_stan/original/3X/e/7/e7cf3b85f8c6b9b4e29f25c95acae8590387066c.png)

Is this valid?

---

<div class="post-metadata">

**Author:** ![Solomon](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/solomon/32/2495_2.png) [@Solomon](https://discourse.mc-stan.org/u/Solomon)\
**Post date:** [October 8, 2025, 8:52pm UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/2 "2025-10-08T20:52:15Z")

</div>

_Note_. I get that setting `lb = 0` and then just dropping unwanted draws is wasteful. I don’t care about that, here. I’m interested in whether this is valid.

---

<div class="post-metadata">

**Author:** ![jsocolar](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jsocolar/32/2486_2.png) [@jsocolar](https://discourse.mc-stan.org/u/jsocolar)\
**Post date:** [October 9, 2025, 2:24am UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/3 "2025-10-09T02:24:12Z")

</div>

Yes, this is valid. Setting lb = 2 is precisely the same thing as truncating the posterior at 2, which is also precisely the distribution you are approximating by MCMC sampling while rejecting values below 2. The latter technique is a form of rejection sampling.

The key intuition here is that samples from a truncated distribution look exactly like samples from the untruncated distribution with all of the samples violating the truncation constraint rejected.

---

<div class="post-metadata">

**Author:** ![Solomon](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/solomon/32/2495_2.png) [@Solomon](https://discourse.mc-stan.org/u/Solomon)\
**Post date:** [October 9, 2025, 2:31am UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/4 "2025-10-09T02:31:35Z")

</div>

Very helpful; thanks!

---

<div class="post-metadata">

**Author:** ![caesoma](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/caesoma/32/19767_2.png) [@caesoma](https://discourse.mc-stan.org/u/caesoma)\
**Post date:** [October 9, 2025, 1:17pm UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/5 "2025-10-09T13:17:27Z")

</div>

> [@Solomon](#):
>
> Are both methods equally valid?

I’d say that is similar to sampling a parameter that is statistically valid, but that doesn’t make sense to the model, e.g. estimating the value of a biological rate that cannot be negative – ideally the data itself would preclude nonsensical values, but we know it’s perfectly possible that estimated values deviate from reality even in the best of the feasible experiments.

The point it what is more sensible, constraining the parameter beforehand or dealing with those values _post hoc_, maybe both are alright and if the sampler doesn’t get stuck at “weird” values, and the latter is helpful to know where inference tends to take the markov chain as a way of challenging your assumptions about the model

> [@Solomon](#):
>
> Further say I want to use those posterior draws from \nu and \sigma to compute a posterior for the standard deviation using the formula \sigma \sqrt{\nu / (\nu - 2)} for \nu \> 2

You could also compute a posterior for the values of \nu that result in finite variance and have a distribution that doesn’t add to one, complementing those with values where the variance is infinity and undefined (of if it’s useful you could even add that to the plot or summary)

> [@Solomon](#):
>
> [  
> Screenshot 2025-10-08 at 3.43.38 PM1232×592 17.8 KB  
> ](https://canada1.discourse-cdn.com/flex030/uploads/mc_stan/original/3X/5/a/5aec5f36f8d820971181a70a4e1fda88f4b827d3.png)

)

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex030/uploads/mc_stan/original/3X/1/9/190baba5d6cf7e2bde3ad3a6c819fe8b7fb79243.png) [@system](https://discourse.mc-stan.org/u/system)\
**Post date:** [October 4, 2026, 1:17pm UTC](https://discourse.mc-stan.org/t/drop-draws-below-a-threshold-rather-than-setting-a-lower-bound-on-a-prior-for-nu/40476/6 "2026-10-04T13:17:47Z")

</div>

This topic was automatically closed 360 days after the last reply. New replies are no longer allowed.
