mjskay / tidybayes

Bayesian analysis + tidy data + geoms (R package)
http://mjskay.github.io/tidybayes
GNU General Public License v3.0
712 stars 59 forks source link

Add more complete prior plotting example to tidy-brms vignette #226

Closed mjskay closed 3 years ago

mjskay commented 4 years ago

See e.g. here: https://github.com/paul-buerkner/brms/issues/694#issuecomment-581065436

mjskay commented 3 years ago

given all the distributional examples and whatnot I think we're okay on this front atm.

lnalborczyk commented 1 year ago

Thank you for documenting this question!

Is there a way of retrieving prior draws from a brms model (fitted with sample_prior = yes) and to manipulate these draws with the usual tidybayes functions (e.g., spread_draws() etc)?

Thank you!

Ladislas

mjskay commented 1 year ago

Should work as per usual when sample_prior = "only". Is there a use case where that does not give what you need?

lnalborczyk commented 1 year ago

It works indeed with a brmsfit model that only includes prior draws, thanks! I was wondering whether there is a way of separating prior and posterior draws from a brmsfit model including both prior and posterior draws (i.e., sample_prior = "yes"), like the distinction between brms::prior_draws() and brms::posterior_draws().

mjskay commented 1 year ago

Ah, makes sense.

spread_draws() can accept data frames of draws, which brms::prior_draws() gives you (except it does not have chain information). e.g. if you try it directly you'll get this error:

m |>
  prior_draws() |>
  spread_draws(Intercept)
Error: To use a data frame directly with `tidy_draws()`, it must already be a
  tidy-format data frame of draws: it must have integer-like `.chain`
  `.iteration`, and `.draw` columns with one row per draw.

  The following columns are not integer-like (or are missing):
    `.chain`, `.iteration`, `.draw`

This is for safety reasons: if the data frame is already a long format df of draws (e.g. the same draw gets repeated over multiple rows), I don't want people accidentally generating nonsense output. Since in this case we know that {brms} is producing a data frame where each draw corresponds to one row, we can add the iteration information ourselves. You can do this manually using something like this:

m |>
  prior_draws() |> 
  mutate(.chain = 1L, .iteration = seq_len(n()), .draw = seq_len(n())) |> 
  spread_draws(Intercept)

Or use posterior::as_draws_df() to do it:

m |>
  prior_draws() |> 
  posterior::as_draws_df() |> 
  spread_draws(Intercept)
lnalborczyk commented 1 year ago

Thank you for your detailed answer, it helps a lot!

Sadly enough, prior_draws() seems to discard "random/varying effects" (i.e., parameters starting with r_) and it seems I can not "regex" them in prior_draws(). For instance, this command:

model %>%
    prior_draws(
        variable = c("^b_", "^r_"), regex = TRUE
        ) 

returns an empty object (but it works well for posterior draws, for instance: model %>% as_draws_df(variable = c("^b_", "^r_"), regex = TRUE))... Do you know how I could include "random effects" in what you suggested above?

Thank you for your help!

mjskay commented 1 year ago

Ah, I don't know unfortunately - you might be able to get a better answer to that question on the brms repo or the Stan forums. It might not be possible without sample_prior = only? Sorry I can't be more help there

lnalborczyk commented 1 year ago

No worries, thank you for your help!

mjskay commented 1 year ago

of course!