#' Extract Coefficient Values From a ubmsFit Model
#'
#' @param object A \code{ubmsFit} model
#' @param ... Currently ignored
#'
#' @return A vector of coefficient values for all submodels.
#'
#' @importFrom unmarked coef
#' @export
setMethod("coef", "ubmsFit", function(object, ...){
unlist(lapply(submodel_types(object), function(x){
s <- summary(object, x)
out <- s$mean
names(out) <- paste0(object[x]@type,"[",rownames(s),"]")
out
}))
})
#' Plot Residuals For All Submodels in a ubmsFit Model
#'
#' @param x A \code{ubmsFit} model
#' @param y Currently ignored
#' @param ... Currently ignored
#'
#' @return A plot object of class \code{gtable} with one panel per submodel.
#'
#' @importFrom gridExtra grid.arrange
#' @importFrom graphics plot
#' @export
setMethod("plot", "ubmsFit", function(x, ...){
pl <- lapply(c("state","det"), function(s) plot_residuals(x, s, draws=6))
grid.arrange(grobs=pl)
})
#' Extract a Submodel from a ubmsFit Model
#'
#' @param x A \code{ubmsFit} model
#' @param i The name of a submodel to extract
#'
#' @return An object of class \code{ubmsSubmodel}.
#'
#' @export
setMethod("[", c("ubmsFit", "character", "missing", "missing"),
function(x, i){
x@submodels[i]
})
#' Get Parameter Names From a ubmsFit Model
#'
#' @param x A \code{ubmsFit} model
#'
#' @return A character vector of parameter names.
#'
#' @export
setMethod("names", "ubmsFit", function(x){
out <- names(x@stanfit)
out[!grepl("log_lik\\[|lp__", out)]
})
#' Get number of Posterior Samples Stored in a ubmsFit Model
#'
#' @param object A \code{ubmsFit} model
#' @param ... Currently ignored
#'
#' @return An integer representing the number of posterior samples
#'
#' @importFrom rstantools nsamples
#' @export
setMethod("nsamples", "ubmsFit", function(object, ...){
sum(object@stanfit@sim$n_save - object@stanfit@sim$warmup2)
})
setMethod("show", "ubmsFit", function(object){
cat("\nCall:\n")
print(object@call)
cat("\n")
for (i in submodel_types(object)){
to_print <- summary(object, i)[,c(1,3,4,8:10),drop=FALSE]
keep_row_names <- nrow(to_print) > 1
names(to_print)[1:2] <- c("Estimate", "SD")
cat(paste0(object[i]@name, get_link_name(object[i]),":\n"))
print(to_print, row.names=keep_row_names, digits=3)
cat("\n")
}
cat(paste0("LOOIC: ", round(object@loo$estimates[3,1], 3)))
cat("\n")
cat("Runtime:", get_runtime(object))
cat("\n")
})
get_link_name <- function(submodel){
switch(submodel@link,
"plogis" = {" (logit-scale)"},
"exp" = {" (log-scale)"}
)
}
#' Extract Summary Statistics from a ubmsFit Model
#'
#' @param object A \code{ubmsFit} model
#' @param submodel Name of submodel to summarize
#' @param probs Numeric vector of quantiles of interest
#' @param ... Currently ignored
#'
#' @return An object of class \code{data.frame} containing summary statistics
#' for posterior distributions of parameters from the chosen submodel.
#'
#' @importFrom unmarked summary
#' @export
setMethod("summary", "ubmsFit",
function(object, submodel, probs = c(0.025,0.25,0.5,0.75,0.975), ...){
sm <- object[submodel]
out <- rstan::summary(object@stanfit, beta_par(sm), probs = probs)
out <- as.data.frame(out$summary)
rownames(out) <- beta_names(sm)
if(has_random(sm)){
random <- rstan::summary(object@stanfit, sig_par(sm), probs = probs)
random <- as.data.frame(random$summary)
rownames(random) <- sigma_names(sm)
out <- rbind(out, random)
}
if(has_spatial(sm)){
tau <- rstan::summary(object@stanfit, "tau", probs = probs)
tau <- as.data.frame(tau$summary)
rownames(tau) <- "RSR [tau]"
out <- rbind(out, tau)
}
out
})
#' Extract y, the Response Variable, From a ubmsFit Model
#'
#' @param object A \code{ubmsFit} model
#'
#' @return A matrix containing the response variable \code{y}.
#'
#' @importFrom unmarked getY
#' @export
setMethod("getY", "ubmsFit", function(object){
object@data@y
})
#' Leave-one-out Cross Validation
#'
#' @param x A \code{ubmsFit} model
#' @param ... Currently ignored
#' @param cores Number of cores to use for calculation
#'
#' @return A named list of class \code{loo} with estimates of
#' the expected log predictive density and other parameters used
#' for model comparison. See \code{?loo::loo} for more information.
#'
#' @importFrom loo loo
#' @export
setMethod("loo", "ubmsFit", function(x, ..., cores=getOption("mc.cores", 1)){
loglik <- extract_log_lik(x, merge_chains=FALSE)
r_eff <- loo::relative_eff(exp(loglik), cores=cores)
loo::loo(loglik, r_eff=r_eff, cores=cores)
})
#' Widely Applicable Information Criterion (WAIC)
#'
#' @param x A \code{ubmsFit} model
#' @param ... Currently ignored
#'
#' @return An object of class \code{waic} containing an estimate of WAIC and
#' other parameters useful for model comparison. See \code{?loo::waic} for
#' more information.
#'
#' @importFrom loo waic
#' @export
setMethod("waic", "ubmsFit", function(x, ...){
loglik <- extract_log_lik(x)
loo::waic(loglik)
})
#' Extract Samples From a ubmsFit Model
#'
#' Extract samples from a \code{ubmsFit} model
#'
#' @param object A \code{ubmsFit} object
#' @param pars An optional character vector providing parameter
#' names of interest. If not specified, all parameters are used
#' @param permuted Logical. If \code{TRUE}, draws are permuted
#' and merged; if \code{FALSE}, the original order is kept
#' @param inc_warmup Logical. If \code{TRUE}, warmup iterations
#' are included; if \code{FALSE} they are discarded.
#' @param include Logical. If \code{TRUE} provided parameter names
#' in \code{pars} are kept; if \code{FALSE} they are excluded.
#'
#' @return If \code{permuted=TRUE}, a list; if \code{permuted=FALSE},
#' an array.
#'
#' @importFrom rstan extract
#' @export
setMethod("extract", "ubmsFit",
function(object, pars, permuted=TRUE, inc_warmup=FALSE, include=TRUE){
rstan::extract(object@stanfit, pars, permuted, inc_warmup, include)
})
#' Markov Chain Traceplots
#'
#' Draws traceplots for chains from a \code{ubmsFit} object
#'
#' @param object A \code{ubmsFit} object
#' @param ... Arguments passed to \code{rstan::traceplot}
#'
#' @return A \code{ggplot} object.
#'
#' @importFrom rstan traceplot
#' @export
setMethod("traceplot", "ubmsFit", function(object, ...){
rstan::traceplot(object@stanfit, ...)
})
#' Get Model Runtime
#'
#' Get warmup and sampling time from a \code{ubmsFit} object
#'
#' @param object A \code{ubmsFit} object
#' @param ... Arguments passed to \code{rstan::get_elapsed_time}
#'
#' @return A matrix with one row per chain and two columns, containing
#' the warmup time and sampling time, respectively, in seconds
#'
#' @importFrom rstan get_elapsed_time
#' @export
setMethod("get_elapsed_time", "ubmsFit", function(object, ...){
rstan::get_elapsed_time(object@stanfit, ...)
})
# Get total model runtime to display in output of show() method
get_runtime <- function(object){
units <- 'sec'
chain_time <- get_elapsed_time(object)
if(was_parallel(object)){
total_time <- max(apply(chain_time, 1, sum))
} else {
total_time <- sum(chain_time)
}
if(total_time > 100){
units <- 'min'
total_time <- total_time / 60
}
if(total_time > 100){
units <- 'hr'
total_time <- total_time / 60
}
paste(sprintf("%.3f", round(total_time, 3)), units)
}
# Check if chains were run in parallel
was_parallel <- function(object){
if(!is.null(object@call$cores) && object@call$cores > 1) return(TRUE)
if(getOption("mc.cores", 1L) > 1) return(TRUE)
FALSE
}
#' Get Stan Code From Model
#'
#' Get the Stan code used to run a model as a character string
#'
#' @param object A \code{ubmsFit} object
#' @param ... Arguments passed to \code{rstan::get_stancode}
#'
#' @return A character string with the model code
#'
#' @details Pass the result of \code{get_stancode} to \code{cat} to get the
#' code in a more readable format. Note that the output in most cases
#' is Stan code that can be used to fit several types of models, and not
#' all Stan code will be used in all models.
#'
#' @importFrom rstan get_stancode
#'
#' @export
setMethod("get_stancode", "ubmsFit", function(object, ...){
rstan::get_stancode(object@stanfit, ...)
})
# Re-create inputs
rebuild_inputs <- function(object){
inps <- build_stan_inputs(object@stanfit@model_name, object@response,
object@submodels, loglik_saved(object))
inps$submodels <- object@submodels
inps
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.