Nothing
# Copyright Brian Keller 2025, all rights reserved
#' Internal function for obtaining data set with one parameter
#' @param model an [`blimp_obj`]
#' @param parameter selection used to obtain data
#' @noRd
make_plot_data <- function(model, parameter) {
# Check it is length 1
if (length(parameter) != 1) throw_error("Unable to Determine Parameter for: {parameter}")
# Get parameter number
param_num <- if (is.numeric(parameter)) {
parameter
} else if (is.character(parameter)) {
# Check estimate names
c(
grep(tolower(parameter), tolower(rownames(model@estimates)), fixed = TRUE),
grep(tolower(parameter), tolower(names(model@iterations)), fixed = TRUE)
)
} else throw_error("Unable to Determine Parameter for: {parameter}")
# Make sure that param_num is length 1
if (length(param_num) != 1) throw_error("Unable to Determine Parameter for: {parameter}")
# Create plot data
plot_data <- data.frame(Parameter = model@iterations[, param_num])
plot_data$`Parameter Type` <- attr(model@iterations, "parameter_type")[param_num]
plot_data$param_num <- param_num
plot_data$param_nam <- rownames(model@estimates)[param_num]
plot_data$Outcome <- attr(model@iterations, "outcome_name")[param_num]
# Return data
return(plot_data)
}
#' Internal function for creating facet labeller function
#' @param pnames a vector of parameter names
#' @param quants a matrix of quantiles
#' @importFrom ggplot2 as_labeller
#' @noRd
make_labeller <- function(pnames, quants) {
force(pnames)
force(quants)
ggplot2::as_labeller(
function(value) {
i <- as.integer(value)
paste0(
pnames[i], "\n",
sprintf("Estimate = %.3f 95%% CI = [%.3f, %.3f]", quants[i,2], quants[i,1], quants[i,3])
)
}
)
}
#' Function to generate graph posterior density plots for parameters
#' @description
#' Generates [`ggplot2::ggplot`] plots using [`ggplot2::geom_density`] based on the output from [`rblimp`]
#' @param model an [`blimp_obj`].
#' @param selector a name of a variable, a name of a parameter, a number of a parameter,
#' or a combination of any of them. If left empty, a plot of all parameters will be returned. See Examples.
#' @param ... arguments passed to internally called [`ggplot2::facet_wrap`] when used.
#' @returns a [`ggplot2::ggplot`] plot
#' @details
#' To change colors use ggplot2's scale system. Both fill and color are used. See
#' [`ggplot2::aes_colour_fill_alpha`] for more information about setting a manual set of colors.
#'
#' @examplesIf has_blimp()
#' # Generate Data
#' mydata <- rblimp_sim(
#' c(
#' 'x ~ normal(0, 1)',
#' 'm ~ normal(0, 1)',
#' 'y ~ normal(10 + 0.5*x + m + 0.2*x*m, 1)'
#' ),
#' n = 100,
#' seed = 981273
#' )
#'
#' # Run Rblimp
#' m1 <- rblimp(
#' c(
#' 'y ~ x m',
#' 'x ~~ m'
#' ),
#' mydata,
#' seed = 10972,
#' burn = 1000,
#' iter = 1000
#' )
#'
#' # Generate plot of all parameters with `y`
#' posterior_plot(m1, 'y') + ggplot2::theme_minimal()
#'
#' # Generate plot of all parameters
#' posterior_plot(m1) + ggplot2::theme_minimal()
#'
#' # Generate plot of all parameters for `y` and `x`
#' posterior_plot(m1, c('x', 'y')) + ggplot2::theme_minimal()
#' # Generate Plot of Parameter 5
#' posterior_plot(m1, 5) + ggplot2::theme_minimal()
#'
#' # Generate plot of `x residual variance`
#' posterior_plot(m1, 'x residual variance') + ggplot2::theme_minimal()
#'
#' # Generate plot of Parameters 7 and 9
#' posterior_plot(m1, c(7, 9)) + ggplot2::theme_minimal()
#' @import ggplot2
#' @importFrom stats quantile
#' @importFrom methods is
#' @export
posterior_plot <- function(
model, selector,
...
) {
# Check model
if (!is(model, 'blimp_obj')) throw_error(
"{.arg model} is not a `blimp_obj`"
)
# Set missing selector to NULL
if (missing(selector)) selector <- NULL
# Create empty list
feature_list <- list()
# Get outcome names
oname <- attr(model@iterations, "outcome_name")
# Determine type of plot
# Produce all plots
if (length(selector) == 0) {
selector <- NROW(model@estimates) |> seq_len()
# Add to feature list
feature_list <- list(ggplot2::ggtitle("Posterior Distributions for All Parameters"))
}
# Handle length 1
if (length(selector) == 1) {
# Check if variable or parameter
o <- grep(paste0('\\b', selector, '\\b'), oname, ignore.case = TRUE)
# If variable name return all parameters and new title
if (length(o) > 0) {
return(
posterior_plot(model, o, ...)
+ ggplot2::ggtitle(
paste0("Posterior Distributions for ", selector, " Model Parameters"),
)
)
} else {
plot_data <- make_plot_data(model, selector)
quant <- quantile(plot_data$Parameter, probs = c(0.025, 0.500, 0.975))
feature_list <- list(
ggplot2::ggtitle(
paste0("Posterior Distribution for ", plot_data$param_nam[1]),
sprintf("Estimate = %.3f 95%% CI = [%.3f, %.3f]", quant[2], quant[1], quant[3])
)
)
}
}
# Otherwise handle multiple
else {
# Check if variable or parameter
olist <- lapply(selector, \(x) {
if (is.numeric(x)) list() # Return empty if it is a number
else
grep(paste0('\\b', x, '\\b'), oname, ignore.case = TRUE) |> as.list()
})
for (i in seq_along(olist)) {
if (length(olist[[i]]) == 0) olist[[i]] <- selector[i]
}
selector <- Reduce(c, olist) # update selector
# Get plot data
plot_data <- selector |> lapply(make_plot_data, model = model) |>
do.call(rbind, args = _)
# Build function for facet labels
make_label <- make_labeller(
rownames(model@estimates),
model@iterations |>
apply(2, quantile, probs = c(0.025, 0.500, 0.975)) |> t()
)
# Create feature list
if (length(feature_list) == 0) {
feature_list <- list(
ggplot2::ggtitle("Posterior Distributions for Selected Parameters"),
ggplot2::facet_wrap(
~ as.factor(param_num), scales = "free", labeller = make_label,
...
)
)
}
# otherwise only add wrap because already has title
else {
feature_list <- c(
feature_list,
list(ggplot2::facet_wrap(
~ as.factor(param_num), scales = "free", labeller = make_label,
...
))
)
}
}
# Suppress R CMD check NOTEs about ggplot2 NSE
Parameter <- `Parameter Type` <- x <- NULL
# Return Plot information
return(
ggplot2::ggplot(plot_data, ggplot2::aes(Parameter))
+ ggplot2::geom_density(
ggplot2::aes(color = `Parameter Type`, fill = `Parameter Type`), alpha = .25
)
+ ggplot2::stat_summary(
ggplot2::aes(xintercept = ggplot2::after_stat(x), y = 0), fun = quantile, geom = "vline",
fun.args = list(probs = c(0.025, 0.500, 0.975)),
orientation = "y"
)
+ ylab('Density') + feature_list
)
}
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.