Nothing
#' @title Update a brma Fit
#'
#' @description
#' Extends an existing fitted \code{brma} object by additional MCMC samples,
#' updates study labels, and optionally recomputes cached fit-dependent
#' quantities.
#'
#' @param object a fitted \code{brma} object.
#' @param formula. unsupported; included for compatibility with
#' \code{\link[stats]{update}}.
#' @param ... unsupported additional arguments.
#' @param sample_extend integer. Number of additional samples per chain.
#' @param slab optional character vector of study labels. Updating labels does
#' not refit or extend the model.
#' @param autofit_control list of autofit control settings. Values are merged
#' with the existing settings before extending.
#' @param convergence_checks list of convergence check settings. Values are
#' merged with the existing settings and used to re-check the fit.
#' @param recompute whether cached \code{loo}, \code{waic}, and
#' \code{marglik} values already stored in \code{object} should be recomputed
#' after extension (\code{"all"}) or dropped with a warning (\code{"drop"}).
#' @param parallel logical. Whether to extend chains in parallel.
#' @param cores integer. Number of cores to use when \code{parallel = TRUE}.
#' @param silent logical. Whether to suppress JAGS output during extension.
#' @param seed optional seed used before extending.
#' @param evaluate unsupported; included for compatibility with
#' \code{\link[stats]{update}}.
#'
#' @return The updated \code{brma} object.
#'
#' @details
#' Extending a fit adds posterior samples only. It does not rerun adaptation or
#' burn-in. Prior, data, and model-structure updates are intentionally not
#' supported by this method.
#'
#' @examples \dontrun{
#' fit <- update(fit, sample_extend = 1000)
#' fit <- update(fit, slab = paste("Study", seq_len(nobs(fit))))
#' }
#'
#' @export
update.brma <- function(
object, formula. = NULL, ...,
sample_extend = NULL, slab = NULL,
autofit_control = NULL, convergence_checks = NULL,
recompute = c("all", "drop"),
parallel = NULL, cores = NULL, silent = NULL, seed = NULL,
evaluate = TRUE) {
if (!inherits(object, "brma")) {
stop("'object' must be a 'brma' object.", call. = FALSE)
}
if (!is.null(formula.)) {
stop("Updating formulas is not supported by update.brma().", call. = FALSE)
}
if (!isTRUE(evaluate)) {
stop("update.brma() does not support 'evaluate = FALSE'.", call. = FALSE)
}
dots <- list(...)
.check_unused_dots(
dots = dots,
allowed = character(0),
caller = "update.brma()"
)
recompute <- match.arg(recompute)
if (!is.null(sample_extend)) {
BayesTools::check_int(
sample_extend,
"sample_extend",
lower = 1,
allow_NA = FALSE
)
}
if (!is.null(slab)) {
object <- .update_brma_slab(object = object, slab = slab)
}
object[["fit_control"]] <- .update_fit_control(
old_fit_control = object[["fit_control"]],
chains = NULL,
adapt = NULL,
burnin = NULL,
sample = NULL,
thin = NULL,
autofit = NULL,
parallel = parallel,
cores = cores,
silent = silent,
seed = seed
)
object[["autofit_control"]] <- .update_autofit_control(
old_autofit_control = object[["autofit_control"]],
autofit_control = .update_brma_autofit_input(
autofit_control = autofit_control,
sample_extend = sample_extend
)
)
object[["convergence_checks"]] <- .update_convergence_checks(
old_convergence_checks = object[["convergence_checks"]],
convergence_checks = convergence_checks
)
fit_extended <- !is.null(sample_extend)
cached <- .collect_brma_fit_cache(object)
if (fit_extended) {
object <- .extend_brma_fit_once(object)
object[["summary"]] <- .object_summary(object)
object[["coefficients"]] <- .object_coefficients(object)
object <- .refresh_brma_fit_cache(
object = object,
cached = cached,
recompute = recompute
)
} else if (!is.null(convergence_checks)) {
object[["fit"]] <- .recheck_brma_fit(object)
}
return(object)
}
# Update study labels without touching the posterior fit.
.update_brma_slab <- function(object, slab) {
outcome <- object[["data"]][["outcome"]]
if (length(slab) != nrow(outcome)) {
stop(
"The 'slab' argument must have length ",
nrow(outcome),
" (same as the fitted data).",
call. = FALSE
)
}
object[["data"]][["outcome"]][["slab"]] <- as.character(slab)
attr(object[["data"]], "slab") <- TRUE
return(object)
}
# Merge update-time autofit settings before validation.
.update_brma_autofit_input <- function(autofit_control, sample_extend) {
if (is.null(autofit_control)) {
autofit_control <- list()
}
if (!is.null(sample_extend)) {
autofit_control[["sample_extend"]] <- sample_extend
}
return(autofit_control)
}
# Extend exactly one sample_extend chunk, even when stored max_extend is larger.
.extend_brma_fit_once <- function(object) {
if (is.null(object[["fit"]]) || length(object[["fit"]]) == 0L) {
stop("'object' does not contain a fitted model to extend.", call. = FALSE)
}
stored_autofit_control <- object[["autofit_control"]]
extend_autofit_control <- stored_autofit_control
extend_autofit_control[["max_extend"]] <- 1
extend_autofit_control <- BayesTools::JAGS_check_and_list_autofit_settings(
autofit_control = extend_autofit_control
)
object[["autofit_control"]] <- extend_autofit_control
object[["fit"]] <- .fit(object, extend = TRUE)
object[["autofit_control"]] <- stored_autofit_control
return(object)
}
# Re-run convergence checks on the current posterior samples.
.recheck_brma_fit <- function(object) {
fit <- object[["fit"]]
if (is.null(fit) || length(fit) == 0L) {
stop("'object' does not contain a fitted model to check.", call. = FALSE)
}
prior_list <- attr(fit, "prior_list")
if (is.null(prior_list)) {
prior_list <- .create_fit_priors(
data = object[["data"]],
priors = object[["priors"]]
)
}
check_fit <- BayesTools::JAGS_check_convergence(
fit = fit,
prior_list = prior_list,
max_Rhat = object[["convergence_checks"]][["max_Rhat"]],
min_ESS = object[["convergence_checks"]][["min_ESS"]],
max_error = object[["convergence_checks"]][["max_error"]],
max_SD_error = object[["convergence_checks"]][["max_SD_error"]]
)
fit[["converged"]] <- check_fit
fit[["has_posterior"]] <- TRUE
fit[["warnings"]] <- c(attr(fit, "warnings"), attr(check_fit, "errors"))
return(fit)
}
# Record which fit-dependent quantities need cache handling after extension.
.collect_brma_fit_cache <- function(object) {
cached <- list(
loo = object[["loo"]],
waic = object[["waic"]],
marglik = object[["marglik"]]
)
return(cached)
}
# Recompute or drop fit-dependent cached quantities after extension.
.refresh_brma_fit_cache <- function(object, cached, recompute) {
cached_names <- .brma_cached_names(cached)
if (length(cached_names) == 0L) {
return(object)
}
object <- .drop_brma_fit_cache(object)
if (recompute == "drop") {
warning(
"Dropping cached ",
paste(cached_names, collapse = ", "),
" because the fit was extended.",
call. = FALSE
)
return(object)
}
object <- .recompute_brma_fit_cache(
object = object,
cached = cached
)
return(object)
}
# Names of cached fit-dependent quantities present in the original object.
.brma_cached_names <- function(cached) {
cached_names <- character(0)
if (!is.null(cached[["loo"]])) {
cached_names <- c(cached_names, "loo")
}
if (!is.null(cached[["waic"]])) {
cached_names <- c(cached_names, "waic")
}
if (!is.null(cached[["marglik"]])) {
cached_names <- c(cached_names, "marglik")
}
return(cached_names)
}
# Remove cached fit-dependent quantities.
.drop_brma_fit_cache <- function(object) {
object[["loo"]] <- NULL
object[["waic"]] <- NULL
object[["marglik"]] <- NULL
return(object)
}
# Recompute the same cached quantities and units that existed before extension.
.recompute_brma_fit_cache <- function(object, cached) {
loo_units <- .brma_cache_units(cached[["loo"]])
for (unit in loo_units) {
object <- add_loo(object, unit = unit)
}
waic_units <- .brma_cache_units(cached[["waic"]])
for (unit in waic_units) {
object <- add_waic(object, unit = unit)
}
if (!is.null(cached[["marglik"]]) && !inherits(object, "RoBMA")) {
object <- add_marglik(object)
}
return(object)
}
# Extract cached LOO/WAIC unit names, accepting a single unnamed legacy cache.
.brma_cache_units <- function(cache) {
if (is.null(cache)) {
return(character(0))
}
units <- names(cache)
if (is.null(units)) {
if (length(cache) == 1L) {
return("estimate")
}
stop("Cached LOO/WAIC objects must be named by unit.", call. = FALSE)
}
units <- units[nzchar(units)]
return(units)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.