bayestestR icon indicating copy to clipboard operation
bayestestR copied to clipboard

Unified bayestestR API

Open mattansb opened this issue 3 years ago • 8 comments

Progress:

  • Posterior Description
    • [ ] describe_posterior
    • [ ] describe_prior
    • [ ] sexit
  • Centrality and Uncertainty
    • [ ] point_estimate
      • [ ] Add printing for multi comp / effect
    • [ ] map_estimate
    • [ ] eti
    • [ ] hdi
    • [ ] ci
  • Effect Existence and Significance
    • Posterior Based Methods
      • [ ] p_direction
      • [ ] p_rope
      • [ ] p_map
      • [ ] p_sig
      • [ ] rope
      • [ ] rope_range
      • [ ] equivalence_test
    • Bayes factors
      • [ ] bayesfactor_parameters
      • [ ] bayesfactor_models
      • [ ] bayesfactor_inclusion
      • [ ] bayesfactor_restricted
      • [ ] si
      • [ ] weighted_posteriors
  • Model Diagnostics
    • [ ] diagnostic_posterior
    • [ ] sensitivity_to_prior - @DominiqueMakowski might want to do this as some other time...
    • [ ] check_prior
    • [ ] simulate_prior
    • [ ] unupdate
    • [ ] effective_sample
    • [ ] mcse
  • Density Estimation
    • [ ] estimate_density

Other:

  • [ ] tests

While working on blavaan support, I've noticed that many of the functions can be simplified to the following:

.foo <- function(x, ...) {...}

foo.data.frame <- function (x, ...){
  out <- data.frame(
    Parameter = names(x),
    Thing = sapply(x, .foo)
  )

  class(out) <- unique(c("foo", "see_foo", class(out)))
  attr(out, "object_name") <- .safe_deparse(substitute(x))
  out
}

foo.default <- function (x, ...){
  stopifnot(model_info(x)$is_bayesian)
  posterior <- insight::get_parameters(x, ...)
  clean_pars <- insight::clean_parameters(x)
  Thing <- foo.data.frame(posterior)
  
  out <- .prepare_output(
    Thing,
    clean_pars
  )
  
  class(out) <- unique(c("foo", "see_foo", class(out)))
  attr(out, "object_name") <- .safe_deparse(substitute(x))
  out
}

This essentially would mean that any bayesian model supported by insight would automatically be supported by bayestestR.

Any additional control can be added either with a simple wrapper, or something like this:

foo.stanreg <- function (x, effects = , component = , parameter = , ...) {
  out <- foo.default(x, effects = , component = , parameter = , is_stanmvreg = inherits(x, "stanmvreg"), ...)


  attr(out, "object_name") <- .safe_deparse(substitute(x))
  out
}

I think this will make expanding support for more models much easier for us and for any one else who just wants to make a PR.

What do you think?

mattansb avatar Mar 10 '21 17:03 mattansb

totally agree, it's true tha for some reasons the bayestestR code feels now very clunky and very redundant (a testimony of how we grew maybe 😏), but I was never too sure on how to best address that...

DominiqueMakowski avatar Mar 11 '21 00:03 DominiqueMakowski

If you are okay with my outline, I can get to work on it. @strengejacke thoughts?

mattansb avatar Mar 11 '21 07:03 mattansb

yeah looks good to me, but then it's not like I'm the maintainer of bayestestR... or am I still 😮 😁

DominiqueMakowski avatar Mar 11 '21 08:03 DominiqueMakowski

Yeah, whenever I added support for some "exotic" model classes, I realized that it mostly boils down to passing the result from get_parameters() to the data frame method. In particular since get_parameters() now can return the posteriors samples (by default) as well as the point estimates (with summary = TRUE), we have much more options simplifying bayestestR.

strengejacke avatar Mar 11 '21 09:03 strengejacke

but then it's not like I'm the maintainer of bayestestR...

You were maintainer of parameters, pass maintainership of correlation to @IndrajeetPatil, effectsize to @mattansb, and now bayestestR - I think you can go now...

han-solo-see-ya

strengejacke avatar Mar 11 '21 09:03 strengejacke

Haha I wanna share the fun I have too much fun on my hands already 😁 (with report that we need to push and all that)

And as a wise jedi master I'm mindful of my shortcomings it seems I'm better at adding new semistable features here and there and coming out with names than thoroughly maintaining the factory... After all I'm french 🤷

DominiqueMakowski avatar Mar 11 '21 09:03 DominiqueMakowski

I started working on this, but it is really f*#&ing hard! A lot harder than I thought (mostly due to the addition of the effects / components / type columns). I'm wondering if it is worth the effort?

Perhaps as an intermediary stage we can just add a default method and with time work our way back? What do you think?

mattansb avatar Mar 18 '21 11:03 mattansb

A default method and working backward seems like a good idea.

bwiernik avatar Jun 23 '21 14:06 bwiernik