From ca1dec6bd89570614e5c161d6b9d4ba4dec509c2 Mon Sep 17 00:00:00 2001 From: Ven Popov Date: Sat, 23 Mar 2024 20:35:55 +0100 Subject: [PATCH] remove deprecated functions; hard dependency on brms 2.21.0 --- .dev/bmm_default_priors.Rmd | 22 ++--- .dev/visualizing_priors.R | 2 +- DESCRIPTION | 4 +- NAMESPACE | 9 +-- NEWS.md | 7 +- R/fit_model.R | 2 +- R/helpers-data.R | 35 ++------ R/helpers-model.R | 74 ++--------------- R/helpers-prior.R | 45 +++-------- R/restructure.R | 16 +--- R/summary.R | 6 +- R/update.R | 6 +- R/zzz.R | 6 -- ...l_prior.Rd => default_prior.bmmformula.Rd} | 29 +++---- man/fit_model.Rd | 2 +- man/make_stancode_parblock.Rd | 44 ---------- ...structure_bmm.Rd => restructure.bmmfit.Rd} | 6 +- ...get_stancode.Rd => stancode.bmmformula.Rd} | 24 ++---- ...get_standata.Rd => standata.bmmformula.Rd} | 21 ++--- tests/testthat/test-helpers-data.R | 40 +++------ tests/testthat/test-helpers-model.R | 81 ++++--------------- tests/testthat/test-helpers-prior.R | 69 ++++------------ tests/testthat/test-restructure.R | 2 +- tests/testthat/test-update.R | 6 +- 24 files changed, 126 insertions(+), 432 deletions(-) rename man/{get_model_prior.Rd => default_prior.bmmformula.Rd} (69%) delete mode 100644 man/make_stancode_parblock.Rd rename man/{restructure_bmm.Rd => restructure.bmmfit.Rd} (85%) rename man/{get_stancode.Rd => stancode.bmmformula.Rd} (65%) rename man/{get_standata.Rd => standata.bmmformula.Rd} (69%) diff --git a/.dev/bmm_default_priors.Rmd b/.dev/bmm_default_priors.Rmd index e0191021..482ffd43 100644 --- a/.dev/bmm_default_priors.Rmd +++ b/.dev/bmm_default_priors.Rmd @@ -89,7 +89,7 @@ All model parameters are `nlpar` so they get class `b` with coef `Intercept` ```{r} model <- mixture3p('dev_rad', nt_features = paste0('col_nt',1:7), setsize='set_size') formula <- bmf(kappa ~ 1, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -102,7 +102,7 @@ For kappa, which we include and intercept and a predictor, we get class `b` with ```{r} formula <- bmf(kappa ~ session, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -115,7 +115,7 @@ For kappa, which we include and intercept and a predictor, we get class `b` with ```{r} formula <- bmf(kappa ~ 0+session, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -126,7 +126,7 @@ terms(formula$kappa) ```{r} formula <- bmf(kappa ~ 0+session + ( 0+session|ID), thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -138,7 +138,7 @@ terms(formula$kappa) ```{r} formula <- bmf(kappa ~ session + cond, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -154,7 +154,7 @@ What we can do, is for each predictor, check how many levels appear. ```{r} formula <- bmf(kappa ~ 0 + session + cond, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -166,7 +166,7 @@ terms(formula$kappa) ```{r} formula <- bmf(kappa ~ 0 + session * cond, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -178,7 +178,7 @@ terms(formula$kappa) ```{r} formula <- bmf(kappa ~ 0 + session:cond + cond + session, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -190,7 +190,7 @@ terms(formula$kappa) ```{r} formula <- bmf(kappa ~ 0 + session:cond, thetat ~ 1, thetant ~ 1) -get_model_prior(formula, dat, model) +default_prior(formula, dat, model) ``` ```{r} @@ -235,11 +235,11 @@ A helper function to compare the priors with and without the default priors. ```{r} compare_priors <- function(formula,dat,model) { - p1 <- withr::with_options(list('bmm.default_priors'=FALSE), get_model_prior(formula, dat, model)) %>% + p1 <- withr::with_options(list('bmm.default_priors'=FALSE), default_prior(formula, dat, model)) %>% brms:::prepare_print_prior() %>% rename(priorBRMS=prior) %>% select(priorBRMS,class,coef,group,resp,dpar,nlpar) - p2 <- withr::with_options(list('bmm.default_priors'=TRUE), get_model_prior(formula, dat, model)) %>% + p2 <- withr::with_options(list('bmm.default_priors'=TRUE), default_prior(formula, dat, model)) %>% brms:::prepare_print_prior() %>% rename(priorBMM=prior) %>% select(priorBMM,class,coef,group,resp,dpar,nlpar) diff --git a/.dev/visualizing_priors.R b/.dev/visualizing_priors.R index 0ed7a4d2..74021af1 100644 --- a/.dev/visualizing_priors.R +++ b/.dev/visualizing_priors.R @@ -2,7 +2,7 @@ data <- OberauerLin_2017 data$session <- as.factor(data$session) formula <- bmf(c ~ 0 + set_size, kappa ~ session) model <- sdmSimple('dev_rad') -get_model_prior(formula, data, model) +default_prior(formula, data, model) x <- exp(rnorm(1000000,3,1.75)) diff --git a/DESCRIPTION b/DESCRIPTION index fd0cd0c6..6399f02a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: bmm Title: Easy and Accesible Bayesian Measurement Models using 'brms' -Version: 0.4.6.9000 +Version: 0.4.7.9000 Authors@R: c( person("Vencislav", "Popov", , "vencislav.popov@gmail.com", role = c("aut", "cre", "cph")), person("Gidon", "Frischkorn", , "gidon.frischkorn@psychologie.uzh.ch", role = c("aut", "cph")), @@ -53,5 +53,5 @@ Additional_repositories: VignetteBuilder: knitr Depends: R (>= 3.6.0), - brms + brms (>= 2.21.0) LazyData: true diff --git a/NAMESPACE b/NAMESPACE index ed314f5c..f14b757a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,6 +29,7 @@ S3method(configure_prior,IMMfull) S3method(configure_prior,bmmmodel) S3method(configure_prior,default) S3method(configure_prior,mixture3p) +S3method(default_prior,bmmformula) S3method(fit_info,brmsfit) S3method(fit_info,brmsfit_list) S3method(identical,bmmformula) @@ -52,6 +53,7 @@ S3method(reset_env,brmsfamily) S3method(reset_env,brmsformula) S3method(reset_env,default) S3method(reset_env,formula) +S3method(restructure,bmmfit) S3method(revert_postprocess_brm,default) S3method(revert_postprocess_brm,sdmSimple) S3method(rhs_vars,bmmformula) @@ -82,11 +84,7 @@ export(dmixture3p) export(dsdm) export(fit_info) export(fit_model) -export(get_model_prior) -export(get_stancode) -export(get_standata) export(k2sd) -export(make_stancode_parblock) export(mixture2p) export(mixture3p) export(pIMM) @@ -101,7 +99,6 @@ export(qmixture3p) export(qsdm) export(rIMM) export(rad2deg) -export(restructure_bmm) export(revert_postprocess_brm) export(rmixture2p) export(rmixture3p) @@ -113,6 +110,8 @@ export(supported_models) export(use_model_template) export(wrap) import(stats) +importFrom(brms,default_prior) +importFrom(brms,restructure) importFrom(brms,stancode) importFrom(brms,standata) importFrom(glue,glue) diff --git a/NEWS.md b/NEWS.md index ddb1cb20..b6651cfa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ ### New features * add a custom **summary()** method for bmm models (#144) * add a global options **bmm.summary_backend** to control the backend used for the summary() method (choices are "bmm" and "brms") -* deprecate **get_model_prior(), get_stancode() and get_standata()**. These functions will be removed in future versions of the package. Due to [recent changes](https://github.com/paul-buerkner/brms/pull/1604) in *brms* version 2.20.14, you can now use the *brms* functions `default_prior`, `stancode` and `standata` directly with *bmm* models (alternatively, their older aliases, "get_prior", "make_stancode", "make_standata"). +* BREAKING CHANGE: remove **get_model_prior(), get_stancode() and get_standata()**. Due to [recent changes](https://github.com/paul-buerkner/brms/pull/1604) in *brms* version 2.21.0, you can now use the *brms* functions `default_prior`, `stancode` and `standata` directly with *bmm* models. * function **restructure()** now allows to apply methods introduced in newer bmm versions to bmmfit objects created by older bmm versions * you can now specify any model parameter to be a constant by using an equal sign in the `bmmformula` (#142) * you can now choose to estimate parameters that are fixed to a constant by default for all models (#145) @@ -13,9 +13,12 @@ ### Bug fixes * fix a bug preventing the sort_data check from being executed (#72) -* fix a bug with the summary() function not displaying implicit parameters (#152) +* fix bugs with the summary() function not displaying implicit parameters (#152) and not working properly with some hierarhical designs (#173) * fix a bug in which the sort_data check occured in cases where it shouldn't (#158) +### Other changes +* `bmm` now requires the latest version of `brms` (>= 2.21.0). + # bmm 0.4.0 ### New features diff --git a/R/fit_model.R b/R/fit_model.R index b97e3318..c044da14 100644 --- a/R/fit_model.R +++ b/R/fit_model.R @@ -22,7 +22,7 @@ #' @param chains Numeric. Number of Markov chains (defaults to 4) #' @param prior One or more `brmsprior` objects created by [brms::set_prior()] #' or related functions and combined using the c method or the + operator. See -#' also [get_model_prior()] for more help. Not necessary for the default model +#' also [default_prior()] for more help. Not necessary for the default model #' fitting, but you can provide prior constraints to model parameters #' @param sort_data Logical. If TRUE, the data will be sorted by the predictor #' variables for faster sampling. If FALSE, the data will not be sorted, but diff --git a/R/helpers-data.R b/R/helpers-data.R index 03a7e037..74dc5da2 100644 --- a/R/helpers-data.R +++ b/R/helpers-data.R @@ -221,50 +221,27 @@ rad2deg <- function(rad){ #' this function will return the combined stan data generated by `bmm` and #' `brms` #' -#' @details This function is deprecated. Please use `standata()` or -#' `make_standata()` (if using `brms` >= 2.20.14) instead. In `brms` >= -#' 2.20.14, `make_standata()` became an alias for `standata()`, and -#' `standata()` is the recommended function to use. -#' #' @inheritParams fit_model #' @param object A `bmmformula` object -#' @param formula Deprecated. Use `object` instead. -#' @param ... Further arguments passed to [brms::make_standata()]. See the -#' description of [brms::make_standata()] for more details +#' @param ... Further arguments passed to [brms::standata()]. See the +#' description of [brms::standata()] for more details #' #' @returns A named list of objects containing the required data to fit a bmm #' model with Stan. #' -#' -#' @seealso [supported_models()], [brms::make_standata()], [brms::standata()] +#' @seealso [supported_models()], [brms::standata()] #' #' @export #' #' @keywords extract_info -#' @importFrom brms standata #' #' @examples #' sdata1 <- standata(bmf(c ~ 1, kappa ~ 1), #' data = OberauerLin_2017, #' model = sdmSimple(resp_err = "dev_rad")) #' str(sdata1) +#' @importFrom brms standata #' @export -get_standata <- function(object, data, model, prior=NULL, formula = object, ...) { - if (utils::packageVersion('brms') >= "2.20.14") { - message("get_standata is deprecated. Please use standata() or make_standata() instead.") - } else { - message("get_standata is deprecated. Please use standata() instead.") - } - warnif(missing(object) && !missing(formula), - "The 'formula' argument is deprecated for consistency with brms (>= 2.20.14). \\ - Please use 'object' instead.") - - standata.bmmformula(object = formula, data = data, - model = model, prior = prior, ...) -} - -#' @export -#' @rdname get_standata standata.bmmformula <- function(object, data, model, prior = NULL, ...) { # check model, formula and data, and transform data if necessary formula <- object @@ -281,7 +258,9 @@ standata.bmmformula <- function(object, data, model, prior = NULL, ...) { # extract stan code dots <- list(...) fit_args <- combine_args(nlist(config_args, dots, prior)) - brms::do_call(brms::make_standata, fit_args) + fit_args$object <- fit_args$formula + fit_args$formula <- NULL + brms::do_call(brms::standata, fit_args) } # check if the data is sorted by the predictors diff --git a/R/helpers-model.R b/R/helpers-model.R index 1660e1b0..763e31ea 100644 --- a/R/helpers-model.R +++ b/R/helpers-model.R @@ -608,48 +608,26 @@ use_model_template <- function(model_name, #' @title Generate Stan code for bmm models -#' @description A wrapper around `brms::make_stancode()` for models specified -#' with `bmm`. Given the `model`, the `data` and the `formula` for the model, +#' @description Given the `model`, the `data` and the `formula` for the model, #' this function will return the combined stan code generated by `bmm` and #' `brms` #' #' @inheritParams fit_model #' @param object A `bmmformula` object -#' @param formula Deprecated. Use `object` instead. -#' @param ... Further arguments passed to [brms::make_stancode()]. See the -#' description of [brms::make_stancode()] for more details +#' @param ... Further arguments passed to [brms::stancode()]. See the +#' description of [brms::stancode()] for more details #' -#' @details This function is deprecated. Please use `stancode()` or -#' `make_stancode()` (if using `brms` >= 2.20.14) instead. In `brms` >= -#' 2.20.14, `make_stancode()` became an alias for `stancode()`, and -#' `stancode()` is the recommended function to use. #' @returns A character string containing the fully commented Stan code to fit a #' bmm model. #' -#' @seealso [supported_models()], [brms::make_stancode()] -#' @export +#' @seealso [supported_models()], [brms::stancode()] #' @keywords extract_info -#' @importFrom brms stancode #' @examples #' scode1 <- stancode(bmf(c ~ 1, kappa ~ 1), #' data = OberauerLin_2017, #' model = sdmSimple(resp_err = "dev_rad")) #' cat(scode1) -get_stancode <- function(object, data, model, prior=NULL, formula = object, ...) { - if (utils::packageVersion('brms') >= "2.20.14") { - message("get_stancode is deprecated. Please use stancode() or make_stancode() instead.") - } else { - message("get_stancode is deprecated. Please use stancode() instead.") - } - warnif(missing(object) && !missing(formula), - "The 'formula' argument is deprecated for consistency with brms (>= 2.20.14). \\ - Please use 'object' instead.") - - stancode.bmmformula(object = formula, data = data, - model = model, prior = prior, ...) -} - -#' @rdname get_stancode +#' @importFrom brms stancode #' @export stancode.bmmformula <- function(object, data, model, prior = NULL, ...) { withr::local_options(bmm.sort_data = FALSE) @@ -669,43 +647,7 @@ stancode.bmmformula <- function(object, data, model, prior = NULL, ...) { # extract stan code dots <- list(...) fit_args <- combine_args(nlist(config_args, dots, prior)) - brms::do_call(brms::make_stancode, fit_args) -} - - - -#' @title Get the parameter block from a generated Stan code for bmm models -#' @description A wrapper around `get_stancode()` for models specified with -#' `bmm`. Given the `model`, the `data` and the `formula` for the model, this -#' function will return just the parameters block. Useful for figuring out -#' which paramters you can set initial values on -#' @inheritParams fit_model -#' @param ... Further arguments passed to [brms::make_stancode()]. See the -#' description of [brms::make_stancode()] for more details -#' -#' @keywords extract_info -#' -#' @returns A character string containing the parameter block of fully commented -#' Stan code to fit a bmm model. -#' -#' -#' @seealso [supported_models()], [get_stancode()] -#' -#' @export -make_stancode_parblock <- function(formula, data, model, prior=NULL, ...) { - stancode <- get_stancode(formula, data, model, prior, ...) - .extract_parblock(stancode) -} - - -#' @title Extract the parameter block from the Stan code -#' @description Given the Stan code for a model, this function will extract the -#' parameter block from the Stan code -#' @param stancode A character string containing the fully commented Stan code -#' @noRd -.extract_parblock <- function(stancode) { - parblock <- stringr::str_match(as.character(stancode), - "(?s)parameters \\{\\n(.*?)\\}\\ntransformed")[,2] - class(parblock) <- class(stancode) - parblock + fit_args$object <- fit_args$formula + fit_args$formula <- NULL + brms::do_call(brms::stancode, fit_args) } diff --git a/R/helpers-prior.R b/R/helpers-prior.R index 41f1e4ab..39a7eb0d 100644 --- a/R/helpers-prior.R +++ b/R/helpers-prior.R @@ -8,54 +8,31 @@ #' need to be specified and also know which priors were used if no #' user-specified priors were passed to the [fit_model()] function. #' +#' The default priors in `bmm` tend to be more informative than the default +#' priors in `brms`, as we use domain knowledge to specify the priors. +#' #' @inheritParams fit_model #' @param object A `bmmformula` object -#' @param formula Deprecated. Use `object` instead. -#' @param ... Further arguments passed to \code{\link[brms:get_prior]{brms::get_prior()}}. See the -#' description of \code{\link[brms:get_prior]{brms::get_prior()}} for more details -#' -#' @details This function is deprecated. Please use `default_prior()` or `get_prior()` (if using -#' `brms` >= 2.20.14) instead. In `brms` >= 2.20.14, `get_prior()` became an -#' alias for `default_prior()`, and `default_prior()` is the recommended function to use. +#' @param ... Further arguments passed to [brms::default_prior()] #' #' @returns A data.frame with columns specifying the `prior`, the `class`, the #' `coef` and `group` for each of the priors specified. Separate rows contain #' the information on the parameters (or parameter classes) for which priors #' can be specified. #' -#' @name get_model_prior -#' -#' @seealso [supported_models()], \code{\link[brms:get_prior]{brms::get_prior()}}. +#' @seealso [supported_models()], [brms::default_prior()] #' #' @keywords extract_info #' #' @export #' #' @examples -#' \dontrun{ -#' # if using brms >= 2.20.14 #' default_prior(bmf(c ~ 1, kappa ~ 1), #' data = OberauerLin_2017, #' model = sdmSimple(resp_err = 'dev_rad')) -#' # if using brms < 2.20.14 -#' get_prior(bmf(c ~ 1, kappa ~ 1), -#' data = OberauerLin_2017, -#' model = sdmSimple(resp_err = 'dev_rad')) -#' } +#' @importFrom brms default_prior #' @export -get_model_prior <- function(object, data, model, formula = object, ...) { - fcall <- as.character(match.call()[1]) - if (fcall == "get_model_prior") { - if (utils::packageVersion('brms') >= "2.20.14") { - message("get_model_prior is deprecated. Please use get_prior() or default_prior()") - } else { - message("get_model_prior is deprecated. Please use get_prior() instead.") - } - } - if (missing(object) && !missing(formula)) { - warning2("The 'formula' argument is deprecated for consistency with brms (>= 2.20.14).", - " Please use 'object' instead.") - } +default_prior.bmmformula <- function(object, data, model, formula = object, ...) { withr::local_options(bmm.sort_data = FALSE) formula <- object @@ -67,15 +44,15 @@ get_model_prior <- function(object, data, model, formula = object, ...) { dots <- list(...) prior_args <- combine_args(nlist(config_args, dots, prior)) - brms_priors <- brms::do_call(brms::get_prior, prior_args) + prior_args$object <- prior_args$formula + prior_args$formula <- NULL + + brms_priors <- brms::do_call(brms::default_prior, prior_args) combine_prior(brms_priors, prior_args$prior) } - - - #' @title construct constant priors to fix fixed model parameters #' @param model a `bmmmodel` object #' @param formula a `brmsformula` object diff --git a/R/restructure.R b/R/restructure.R index de46e33d..67ff92ae 100644 --- a/R/restructure.R +++ b/R/restructure.R @@ -12,7 +12,8 @@ #' @keywords transform #' @export #' @importFrom utils packageVersion -restructure_bmm <- function(x, ...) { +#' @importFrom brms restructure +restructure.bmmfit <- function(x, ...) { version <- x$version$bmm if (is.null(version)) { version <- as.package_version('0.2.1') @@ -25,11 +26,7 @@ restructure_bmm <- function(x, ...) { restr_version <- restructure_version.bmm(x) if (restr_version >= current_version) { - if (packageVersion("brms") >= "2.20.15") { - x <- NextMethod('restructure') - } else { - x <- brms::restructure(x) - } + x <- NextMethod('restructure') return(x) } @@ -59,12 +56,7 @@ restructure_bmm <- function(x, ...) { } x$version$bmm_restructure <- current_version - if (packageVersion("brms") >= "2.20.15") { - x <- NextMethod('restructure') - } else { - x <- brms::restructure(x) - } - x + NextMethod('restructure') } restructure_version.bmm <- function(x) { diff --git a/R/summary.R b/R/summary.R index 843daaba..dc3116e8 100644 --- a/R/summary.R +++ b/R/summary.R @@ -8,11 +8,7 @@ #' options(bmm.color_summary = FALSE) or bmm_options(color_summary = FALSE) #' @export summary.bmmfit <- function(object, priors = FALSE, prob = 0.95, robust = FALSE, mc_se = FALSE, ..., backend = 'bmm') { - if (packageVersion('brms') < '2.20.15') { - object <- restructure_bmm(object) - } else { - object <- brms::restructure(object) - } + object <- restructure(object) backend <- match.arg(backend, c('bmm', 'brms')) # get summary object from brms, since it contains a lot of necessary information: diff --git a/R/update.R b/R/update.R index 60d16add..4eb3f530 100644 --- a/R/update.R +++ b/R/update.R @@ -32,11 +32,7 @@ update.bmmfit <- function(object, formula., newdata = NULL, recompile = NULL, .. stop2("You cannot update with a different model. If you want to use a different model, please use `fit_model()` instead.") } - if (packageVersion('brms') < '2.20.15') { - object <- restructure_bmm(object) - } else { - object <- brms::restructure(object) - } + object <- restructure(object) model <- object$bmm$model old_user_formula <- object$bmm$user_formula diff --git a/R/zzz.R b/R/zzz.R index 78cb5ae5..85c1e097 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,11 +1,5 @@ .onLoad <- function(libname, pkgname) { suppressMessages(bmm_options(reset_options = TRUE)) - if (utils::packageVersion('brms') >= '2.20.15') { - registerS3method("default_prior", "bmmformula", get_model_prior, - envir = asNamespace("brms")) - registerS3method("restructure", "bmmfit", restructure_bmm, - envir = asNamespace("brms")) - } } .onAttach <- function(libname, pkgname) { diff --git a/man/get_model_prior.Rd b/man/default_prior.bmmformula.Rd similarity index 69% rename from man/get_model_prior.Rd rename to man/default_prior.bmmformula.Rd index 97080ae5..3cd45586 100644 --- a/man/get_model_prior.Rd +++ b/man/default_prior.bmmformula.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/helpers-prior.R -\name{get_model_prior} -\alias{get_model_prior} +\name{default_prior.bmmformula} +\alias{default_prior.bmmformula} \title{Get Default priors for Measurement Models specified in BMM} \usage{ -get_model_prior(object, data, model, formula = object, ...) +\method{default_prior}{bmmformula}(object, data, model, formula = object, ...) } \arguments{ \item{object}{A \code{bmmformula} object} @@ -19,10 +19,10 @@ number of required arguments which need to be specified within the function call. Call \code{\link[=supported_models]{supported_models()}} to see the list of supported models and their required arguments} -\item{formula}{Deprecated. Use \code{object} instead.} +\item{formula}{An object of class \code{bmmformula}. A symbolic description of the +model to be fitted.} -\item{...}{Further arguments passed to \code{\link[brms:get_prior]{brms::get_prior()}}. See the -description of \code{\link[brms:get_prior]{brms::get_prior()}} for more details} +\item{...}{Further arguments passed to \code{\link[brms:default_prior]{brms::default_prior()}}} } \value{ A data.frame with columns specifying the \code{prior}, the \code{class}, the @@ -39,25 +39,16 @@ model. Additionally, it will return all model parameters that have no prior specified (flat priors). This can help to get an idea about which priors need to be specified and also know which priors were used if no user-specified priors were passed to the \code{\link[=fit_model]{fit_model()}} function. -} -\details{ -This function is deprecated. Please use \code{default_prior()} or \code{get_prior()} (if using -\code{brms} >= 2.20.14) instead. In \code{brms} >= 2.20.14, \code{get_prior()} became an -alias for \code{default_prior()}, and \code{default_prior()} is the recommended function to use. + +The default priors in \code{bmm} tend to be more informative than the default +priors in \code{brms}, as we use domain knowledge to specify the priors. } \examples{ -\dontrun{ -# if using brms >= 2.20.14 default_prior(bmf(c ~ 1, kappa ~ 1), data = OberauerLin_2017, model = sdmSimple(resp_err = 'dev_rad')) -# if using brms < 2.20.14 -get_prior(bmf(c ~ 1, kappa ~ 1), - data = OberauerLin_2017, - model = sdmSimple(resp_err = 'dev_rad')) -} } \seealso{ -\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:get_prior]{brms::get_prior()}}. +\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:default_prior]{brms::default_prior()}} } \keyword{extract_info} diff --git a/man/fit_model.Rd b/man/fit_model.Rd index 7c4406ff..08dbdfb2 100644 --- a/man/fit_model.Rd +++ b/man/fit_model.Rd @@ -33,7 +33,7 @@ their required arguments} \item{prior}{One or more \code{brmsprior} objects created by \code{\link[brms:set_prior]{brms::set_prior()}} or related functions and combined using the c method or the + operator. See -also \code{\link[=get_model_prior]{get_model_prior()}} for more help. Not necessary for the default model +also \code{\link[=default_prior]{default_prior()}} for more help. Not necessary for the default model fitting, but you can provide prior constraints to model parameters} \item{chains}{Numeric. Number of Markov chains (defaults to 4)} diff --git a/man/make_stancode_parblock.Rd b/man/make_stancode_parblock.Rd deleted file mode 100644 index bc5796a7..00000000 --- a/man/make_stancode_parblock.Rd +++ /dev/null @@ -1,44 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/helpers-model.R -\name{make_stancode_parblock} -\alias{make_stancode_parblock} -\title{Get the parameter block from a generated Stan code for bmm models} -\usage{ -make_stancode_parblock(formula, data, model, prior = NULL, ...) -} -\arguments{ -\item{formula}{An object of class \code{bmmformula}. A symbolic description of the -model to be fitted.} - -\item{data}{An object of class data.frame, containing data of all variables -used in the model. The names of the variables must match the variable names -passed to the \code{bmmmodel} object for required argurments.} - -\item{model}{A description of the model to be fitted. This is a call to a -\code{bmmmodel} such as \code{mixture3p()} function. Every model function has a -number of required arguments which need to be specified within the function -call. Call \code{\link[=supported_models]{supported_models()}} to see the list of supported models and -their required arguments} - -\item{prior}{One or more \code{brmsprior} objects created by \code{\link[brms:set_prior]{brms::set_prior()}} -or related functions and combined using the c method or the + operator. See -also \code{\link[=get_model_prior]{get_model_prior()}} for more help. Not necessary for the default model -fitting, but you can provide prior constraints to model parameters} - -\item{...}{Further arguments passed to \code{\link[brms:stancode]{brms::make_stancode()}}. See the -description of \code{\link[brms:stancode]{brms::make_stancode()}} for more details} -} -\value{ -A character string containing the parameter block of fully commented -Stan code to fit a bmm model. -} -\description{ -A wrapper around \code{get_stancode()} for models specified with -\code{bmm}. Given the \code{model}, the \code{data} and the \code{formula} for the model, this -function will return just the parameters block. Useful for figuring out -which paramters you can set initial values on -} -\seealso{ -\code{\link[=supported_models]{supported_models()}}, \code{\link[=get_stancode]{get_stancode()}} -} -\keyword{extract_info} diff --git a/man/restructure_bmm.Rd b/man/restructure.bmmfit.Rd similarity index 85% rename from man/restructure_bmm.Rd rename to man/restructure.bmmfit.Rd index edf21f42..2f7feff5 100644 --- a/man/restructure_bmm.Rd +++ b/man/restructure.bmmfit.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/restructure.R -\name{restructure_bmm} -\alias{restructure_bmm} +\name{restructure.bmmfit} +\alias{restructure.bmmfit} \title{Restructure Old \code{bmmfit} Objects} \usage{ -restructure_bmm(x, ...) +\method{restructure}{bmmfit}(x, ...) } \arguments{ \item{x}{An object of class \code{bmmfit}.} diff --git a/man/get_stancode.Rd b/man/stancode.bmmformula.Rd similarity index 65% rename from man/get_stancode.Rd rename to man/stancode.bmmformula.Rd index 50d718c8..6a7beec0 100644 --- a/man/get_stancode.Rd +++ b/man/stancode.bmmformula.Rd @@ -1,12 +1,9 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/helpers-model.R -\name{get_stancode} -\alias{get_stancode} +\name{stancode.bmmformula} \alias{stancode.bmmformula} \title{Generate Stan code for bmm models} \usage{ -get_stancode(object, data, model, prior = NULL, formula = object, ...) - \method{stancode}{bmmformula}(object, data, model, prior = NULL, ...) } \arguments{ @@ -24,30 +21,21 @@ their required arguments} \item{prior}{One or more \code{brmsprior} objects created by \code{\link[brms:set_prior]{brms::set_prior()}} or related functions and combined using the c method or the + operator. See -also \code{\link[=get_model_prior]{get_model_prior()}} for more help. Not necessary for the default model +also \code{\link[=default_prior]{default_prior()}} for more help. Not necessary for the default model fitting, but you can provide prior constraints to model parameters} -\item{formula}{Deprecated. Use \code{object} instead.} - -\item{...}{Further arguments passed to \code{\link[brms:stancode]{brms::make_stancode()}}. See the -description of \code{\link[brms:stancode]{brms::make_stancode()}} for more details} +\item{...}{Further arguments passed to \code{\link[brms:stancode]{brms::stancode()}}. See the +description of \code{\link[brms:stancode]{brms::stancode()}} for more details} } \value{ A character string containing the fully commented Stan code to fit a bmm model. } \description{ -A wrapper around \code{brms::make_stancode()} for models specified -with \code{bmm}. Given the \code{model}, the \code{data} and the \code{formula} for the model, +Given the \code{model}, the \code{data} and the \code{formula} for the model, this function will return the combined stan code generated by \code{bmm} and \code{brms} } -\details{ -This function is deprecated. Please use \code{stancode()} or -\code{make_stancode()} (if using \code{brms} >= 2.20.14) instead. In \code{brms} >= -2.20.14, \code{make_stancode()} became an alias for \code{stancode()}, and -\code{stancode()} is the recommended function to use. -} \examples{ scode1 <- stancode(bmf(c ~ 1, kappa ~ 1), data = OberauerLin_2017, @@ -55,6 +43,6 @@ scode1 <- stancode(bmf(c ~ 1, kappa ~ 1), cat(scode1) } \seealso{ -\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:stancode]{brms::make_stancode()}} +\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:stancode]{brms::stancode()}} } \keyword{extract_info} diff --git a/man/get_standata.Rd b/man/standata.bmmformula.Rd similarity index 69% rename from man/get_standata.Rd rename to man/standata.bmmformula.Rd index cccc098e..ef49ad76 100644 --- a/man/get_standata.Rd +++ b/man/standata.bmmformula.Rd @@ -1,12 +1,9 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/helpers-data.R -\name{get_standata} -\alias{get_standata} +\name{standata.bmmformula} \alias{standata.bmmformula} \title{Stan data for \code{bmm} models} \usage{ -get_standata(object, data, model, prior = NULL, formula = object, ...) - \method{standata}{bmmformula}(object, data, model, prior = NULL, ...) } \arguments{ @@ -24,13 +21,11 @@ their required arguments} \item{prior}{One or more \code{brmsprior} objects created by \code{\link[brms:set_prior]{brms::set_prior()}} or related functions and combined using the c method or the + operator. See -also \code{\link[=get_model_prior]{get_model_prior()}} for more help. Not necessary for the default model +also \code{\link[=default_prior]{default_prior()}} for more help. Not necessary for the default model fitting, but you can provide prior constraints to model parameters} -\item{formula}{Deprecated. Use \code{object} instead.} - -\item{...}{Further arguments passed to \code{\link[brms:standata]{brms::make_standata()}}. See the -description of \code{\link[brms:standata]{brms::make_standata()}} for more details} +\item{...}{Further arguments passed to \code{\link[brms:standata]{brms::standata()}}. See the +description of \code{\link[brms:standata]{brms::standata()}} for more details} } \value{ A named list of objects containing the required data to fit a bmm @@ -41,12 +36,6 @@ Given the \code{model}, the \code{data} and the \code{formula} for the model, this function will return the combined stan data generated by \code{bmm} and \code{brms} } -\details{ -This function is deprecated. Please use \code{standata()} or -\code{make_standata()} (if using \code{brms} >= 2.20.14) instead. In \code{brms} >= -2.20.14, \code{make_standata()} became an alias for \code{standata()}, and -\code{standata()} is the recommended function to use. -} \examples{ sdata1 <- standata(bmf(c ~ 1, kappa ~ 1), data = OberauerLin_2017, @@ -54,6 +43,6 @@ sdata1 <- standata(bmf(c ~ 1, kappa ~ 1), str(sdata1) } \seealso{ -\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:standata]{brms::make_standata()}}, \code{\link[brms:standata]{brms::standata()}} +\code{\link[=supported_models]{supported_models()}}, \code{\link[brms:standata]{brms::standata()}} } \keyword{extract_info} diff --git a/tests/testthat/test-helpers-data.R b/tests/testthat/test-helpers-data.R index c57c5835..a31de728 100644 --- a/tests/testthat/test-helpers-data.R +++ b/tests/testthat/test-helpers-data.R @@ -195,46 +195,28 @@ test_that("rad2deg returns the correct values for 0, pi/2, 2*pi", { expect_equal(wrap(rad2deg(x), radians = F), rad2deg(wrap(x))) }) -test_that("make_standata() works with brmsformula", { +test_that("standata() works with brmsformula", { ff <- brms::bf(count ~ zAge + zBase * Trt + (1|patient)) - sd <- make_standata(ff, data = brms::epilepsy, family = poisson()) + sd <- standata(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(sd)[1], "standata") }) -test_that("make_standata() works with formula", { +test_that("standata() works with formula", { ff <- count ~ zAge + zBase * Trt + (1|patient) - sd <- make_standata(ff, data = brms::epilepsy, family = poisson()) + sd <- standata(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(sd)[1], "standata") }) -test_that("make_standata() works with bmmformula if brms >= 2.20.14", { - # define formula - ff <- bmmformula(kappa ~ 1, - thetat ~ 1, - thetant ~ 1) - - # simulate data +test_that("standata() works with bmmformula", { + ff <- bmmformula(kappa ~ 1, thetat ~ 1, thetant ~ 1) dat <- OberauerLin_2017 - - # fit the model - if (utils::packageVersion("brms") >= "2.20.14") { - sd <- make_standata(formula = ff, - data = dat, - model = mixture3p(resp_err = "dev_rad", - nt_features = 'col_nt', - setsize = "set_size", regex = T)) - expect_equal(class(sd)[1], "standata") - } - - sd <- standata(ff, - data = dat, - model = mixture3p(resp_err = "dev_rad", + sd <- standata(ff, dat, mixture3p(resp_err = "dev_rad", nt_features = 'col_nt', setsize = "set_size", regex = T)) expect_equal(class(sd)[1], "standata") }) -test_that("get_standata() returns a standata class", { +test_that("standata() returns a standata class", { ff <- bmmformula(kappa ~ 1, thetat ~ 1, thetant ~ 1) @@ -243,9 +225,9 @@ test_that("get_standata() returns a standata class", { nt1_loc = 2, nt2_loc = -1.5) - standata <- get_standata(ff, dat, mixture3p(resp_err = "y" , - nt_features = paste0('nt',1,'_loc'), - setsize = 2)) + standata <- standata(ff, dat, mixture3p(resp_err = "y" , + nt_features = paste0('nt',1,'_loc'), + setsize = 2)) expect_equal(class(standata)[1], "standata") }) diff --git a/tests/testthat/test-helpers-model.R b/tests/testthat/test-helpers-model.R index 982863d8..bc5d36d3 100644 --- a/tests/testthat/test-helpers-model.R +++ b/tests/testthat/test-helpers-model.R @@ -90,86 +90,35 @@ test_that("use_model_template() prevents duplicate models", { } }) - -test_that("get_stancode() returns a string", { - # define formula - ff <- bmmformula( - kappa ~ 1, - thetat ~ 1, - thetant ~ 1 - ) - - # simulate data - dat <- data.frame( - y = rmixture3p(n = 200), - nt1_loc = 2, - nt2_loc = -1.5 - ) - - # fit the model - stancode <- get_stancode(ff, - data = dat, - model = mixture3p(resp_err = "y", nt_features = paste0("nt", 1, "_loc"), setsize = 2) - ) - expect_equal(class(stancode)[1], "character") -}) - -test_that("make_stancode() works with brmsformula", { +test_that("stancode() works with brmsformula", { ff <- brms::bf(count ~ zAge + zBase * Trt + (1 | patient)) - sd <- make_stancode(ff, data = brms::epilepsy, family = poisson()) + sd <- stancode(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(sd)[1], "character") }) -test_that("make_stancode() works with formula", { +test_that("stancode() works with formula", { ff <- count ~ zAge + zBase * Trt + (1 | patient) - sd <- make_stancode(ff, data = brms::epilepsy, family = poisson()) + sd <- stancode(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(sd)[1], "character") }) -test_that("make_stancode() works with bmmformula if brms >= 2.20.14", { - # define formula - ff <- bmmformula( - kappa ~ 1, - thetat ~ 1, - thetant ~ 1 - ) - - # simulate data - dat <- OberauerLin_2017 - - # fit the model - if (utils::packageVersion("brms") >= "2.20.14") { - sd <- make_stancode(ff, - data = dat, - model = mixture3p( - resp_err = "dev_rad", - nt_features = "col_nt", - setsize = "set_size", regex = T - ) - ) - expect_equal(class(sd)[1], "character") - } - - sd <- stancode(ff, - data = dat, - model = mixture3p( - resp_err = "dev_rad", - nt_features = "col_nt", - setsize = "set_size", regex = T - ) +test_that("stancode() works with bmmformula", { + ff <- bmmformula(kappa ~ 1, thetat ~ 1, thetant ~ 1) + sc <- stancode(ff, OberauerLin_2017, model = mixture3p(resp_err = "dev_rad", + nt_features = "col_nt", + setsize = "set_size", + regex = T) ) - expect_equal(class(sd)[1], "character") + expect_equal(class(sc)[1], "character") }) -test_that("no check for with make_stancode function", { +test_that("no check for with stancode function", { withr::local_options('bmm.sort_data' = 'check') - expect_no_message(make_stancode(bmf(kappa ~ set_size, c ~ set_size), - OberauerLin_2017, - sdmSimple('dev_rad'))) + expect_no_message(stancode(bmf(kappa ~ set_size, c ~ set_size), + OberauerLin_2017, + sdmSimple('dev_rad'))) }) - - test_that("change_constants() works", { model <- sdmSimple(resp_err = "y") formula <- bmf(mu ~ set_size, kappa = 3, c ~ 1) diff --git a/tests/testthat/test-helpers-prior.R b/tests/testthat/test-helpers-prior.R index 4fdaf6fa..7ff51fc8 100644 --- a/tests/testthat/test-helpers-prior.R +++ b/tests/testthat/test-helpers-prior.R @@ -1,50 +1,22 @@ -test_that("get_prior() works with brmsformula", { +test_that("default_prior() works with brmsformula", { ff <- brms::bf(count ~ zAge + zBase * Trt + (1 | patient)) - prior <- get_prior(ff, data = brms::epilepsy, family = poisson()) + prior <- default_prior(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(prior)[1], "brmsprior") }) -test_that("get_prior() works with formula", { +test_that("default_prior() works with formula", { ff <- count ~ zAge + zBase * Trt + (1 | patient) - prior <- get_prior(ff, data = brms::epilepsy, family = poisson()) + prior <- default_prior(ff, data = brms::epilepsy, family = poisson()) expect_equal(class(prior)[1], "brmsprior") }) -test_that("get_prior() works with bmmformula if brms >= 2.20.14", { - # define formula - ff <- bmmformula( - kappa ~ 1, - thetat ~ 1, - thetant ~ 1 - ) - - # simulate data - dat <- OberauerLin_2017 - - # fit the model - if (utils::packageVersion("brms") >= "2.20.14") { - prior <- get_prior( - formula = ff, - data = dat, - model = mixture3p( - resp_err = "dev_rad", - nt_features = "col_nt", - setsize = "set_size", regex = T - ) - ) - expect_equal(class(prior)[1], "brmsprior") - - prior2 <- default_prior( - object = ff, - data = dat, - model = mixture3p( - resp_err = "dev_rad", - nt_features = "col_nt", - setsize = "set_size", regex = T - ) - ) - expect_equal(prior, prior2) - } +test_that("default_prior() works with bmmformula", { + ff <- bmmformula(kappa ~ 1, thetat ~ 1, thetant ~ 1) + prior <- default_prior(ff, OberauerLin_2017, mixture3p(resp_err = "dev_rad", + nt_features = "col_nt", + setsize = "set_size", + regex = T)) + expect_equal(class(prior)[1], "brmsprior") }) test_that("combine prior returns a brmsprior object", { @@ -74,24 +46,17 @@ test_that("in combine prior, prior2 overwrites only shared components with prior test_that("default priors are returned correctly", { - if (utils::packageVersion("brms") >= "2.20.14") { - dp <- default_prior(bmf(kappa ~ set_size, thetat ~ set_size), - OberauerLin_2017, - mixture2p('dev_rad')) - } else { - dp <- get_model_prior(bmf(kappa ~ set_size, thetat ~ set_size), - OberauerLin_2017, - mixture2p('dev_rad')) - } - + dp <- default_prior(bmf(kappa ~ set_size, thetat ~ set_size), + OberauerLin_2017, + mixture2p('dev_rad')) expect_equal(dp[dp$coef == "" & dp$class == "b", ]$prior, c("","normal(0, 1)")) expect_equal(dp[dp$coef == "Intercept", ]$prior, c("normal(2, 1)", "logistic(0, 1)")) }) test_that("no check for sort_data with default_priors function", { withr::local_options('bmm.sort_data' = 'check') - res <- capture_messages(get_model_prior(bmf(kappa ~ set_size, c ~ set_size), - OberauerLin_2017, - sdmSimple('dev_rad'))) + res <- capture_messages(default_prior(bmf(kappa ~ set_size, c ~ set_size), + OberauerLin_2017, + sdmSimple('dev_rad'))) expect_false(any(grepl("sort", res))) }) diff --git a/tests/testthat/test-restructure.R b/tests/testthat/test-restructure.R index caacda23..0e2f324a 100644 --- a/tests/testthat/test-restructure.R +++ b/tests/testthat/test-restructure.R @@ -12,7 +12,7 @@ test_that("restructure works", { file <- file.path(path, "../internal/ref_fits", "20240215_v0.2.1_mixture2p_seed-365_6ae900f5a4.rds") old_fit <- readRDS(file) class(old_fit) <- c("bmmfit", class(old_fit)) - new_fit <- restructure_bmm(old_fit) + new_fit <- restructure(old_fit) expect_equal(new_fit$bmm$model$links,.model_mixture2p()$links) }) diff --git a/tests/testthat/test-update.R b/tests/testthat/test-update.R index fa92447d..c89a25f8 100644 --- a/tests/testthat/test-update.R +++ b/tests/testthat/test-update.R @@ -1,10 +1,6 @@ test_that("update.bmmfit works", { skip_on_cran() - if (packageVersion('brms') < '2.20.15') { - fit1 <- restructure_bmm(bmmfit_example1) - } else { - fit1 <- brms::restructure(bmmfit_example1) - } + fit1 <- restructure(bmmfit_example1) data <- fit1$data # formula is replaced