Skip to content

Commit 9ae502c

Browse files
committed
update
1 parent 8388489 commit 9ae502c

5 files changed

Lines changed: 126 additions & 7 deletions

File tree

.DS_Store

0 Bytes
Binary file not shown.

R/plot_psa_distributions.R

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#' Plot sampled PSA parameter distributions
2+
#'
3+
#' \code{plot_psa_distributions} melts PSA draws, classifies parameters
4+
#' prefixes ("p_", "u_", "c_"), optionally caps extreme values by quantiles, and
5+
#' produces separate ridge-density plots per group (Probabilities / Utilities / Costs / Other).
6+
#'
7+
#' @param df_psa_random data frame of PSA draws (rows = draws, columns = parameters).
8+
#' Only numeric columns are used.
9+
#' @param cap_quantiles numeric length-2 vector (in (0,1)) giving lower/upper quantiles
10+
#' for optional capping, e.g., \code{c(0.01, 0.99)}. Use \code{NULL} to disable capping.
11+
#' Default = c(0.01, 0.99).
12+
#' @param base_size base font size for \code{theme_bw}. Default = 14.
13+
#' @param scale ridge height scaling for \code{geom_density_ridges}. Default = 1.5.
14+
#' @param rel_min_height minimum ridge height to display. Default = 0.01.
15+
#' @param print_group_table print \code{table(df_melt$Group)} for a quick check. Default = TRUE.
16+
#' @return
17+
#' a named list containing:
18+
#' \itemize{
19+
#' \item \code{df_melt}: long-format data with \code{Parameter}, \code{value}, \code{Group}
20+
#' \item \code{group_table}: frequency table of groups
21+
#' \item \code{plots}: named list of ggplot objects for "Probabilities", "Utilities",
22+
#' "Costs", and "Other" (missing groups return \code{NULL})
23+
#' }
24+
#' @examples
25+
#' \donttest{
26+
#' set.seed(1); n <- 1000
27+
#' df <- data.frame(
28+
#' p_event = rbeta(n, 2, 8), p_death = rbeta(n, 5, 3),
29+
#' u_base = rbeta(n, 20, 5), u_treated = pmin(pmax(rnorm(n, .82, .06), 0), 1),
30+
#' c_tx = rgamma(n, 2, 0.001), c_hosp = rgamma(n, 3, 0.005),
31+
#' other_noise = rnorm(n, 10, 1)
32+
#' )
33+
#'
34+
#' # Separate panels: one plot per group; no global capping to keep axes sensible.
35+
#' out <- plot_psa_distributions(df, cap_quantiles = NULL)
36+
#' out$group_table
37+
#'
38+
#' # Print each panel (Probabilities / Utilities / Costs / Other if present)
39+
#' for (nm in c("Probabilities", "Utilities", "Costs", "Other")) {
40+
#' if (!is.null(out$plots[[nm]])) print(out$plots[[nm]])
41+
#' }
42+
#' }
43+
#' @export
44+
plot_psa_distributions <- function(df_psa_random,
45+
cap_quantiles = c(0.01, 0.99),
46+
base_size = 14,
47+
scale = 1.5,
48+
rel_min_height = 0.01,
49+
print_group_table = TRUE) {
50+
# deps via :: to keep lightweight
51+
if (!requireNamespace("reshape2", quietly = TRUE)) stop("Please install.packages('reshape2').")
52+
if (!requireNamespace("dplyr", quietly = TRUE)) stop("Please install.packages('dplyr').")
53+
if (!requireNamespace("stringr", quietly = TRUE)) stop("Please install.packages('stringr').")
54+
if (!requireNamespace("ggplot2", quietly = TRUE)) stop("Please install.packages('ggplot2').")
55+
if (!requireNamespace("ggridges", quietly = TRUE)) stop("Please install.packages('ggridges').")
56+
57+
# keep only numeric columns
58+
stopifnot(is.data.frame(df_psa_random))
59+
num_cols <- vapply(df_psa_random, is.numeric, logical(1))
60+
if (!any(num_cols)) stop("No numeric columns found in df_psa_random.")
61+
df_num <- df_psa_random[, num_cols, drop = FALSE]
62+
63+
# Melt the dataset (as in the example)
64+
df_melt <- reshape2::melt(df_num, variable.name = "Parameter", value.name = "value")
65+
66+
# Optionally cap extreme values (global, like the example)
67+
xlim_global <- NULL
68+
if (!is.null(cap_quantiles) && length(cap_quantiles) == 2) {
69+
q <- stats::quantile(df_melt$value, probs = cap_quantiles, na.rm = TRUE)
70+
df_melt <- df_melt[df_melt$value >= q[[1]] & df_melt$value <= q[[2]], , drop = FALSE]
71+
xlim_global <- c(q[[1]], q[[2]])
72+
}
73+
74+
# Create a new column to classify parameters by prefix (as in the example)
75+
df_melt <- dplyr::mutate(
76+
df_melt,
77+
Group = dplyr::case_when(
78+
stringr::str_starts(Parameter, "p_") ~ "Probabilities",
79+
stringr::str_starts(Parameter, "u_") ~ "Utilities",
80+
stringr::str_starts(Parameter, "c_") ~ "Costs",
81+
TRUE ~ "Other"
82+
)
83+
)
84+
85+
# Optionally check the groups
86+
group_tab <- table(df_melt$Group)
87+
if (isTRUE(print_group_table)) print(group_tab)
88+
89+
# Helper to draw one group's ridges (NULL if empty)
90+
mk_plot <- function(dat, title_txt) {
91+
if (nrow(dat) == 0) return(NULL)
92+
# order y by median for readability
93+
ord <- dat |>
94+
dplyr::group_by(Parameter) |>
95+
dplyr::summarise(.med = stats::median(value, na.rm = TRUE), .groups = "drop") |>
96+
dplyr::arrange(.med)
97+
dat$Parameter <- factor(dat$Parameter, levels = ord$Parameter)
98+
99+
p <- ggplot2::ggplot(dat, ggplot2::aes(x = value, y = Parameter)) +
100+
ggridges::geom_density_ridges(scale = scale, rel_min_height = rel_min_height, linewidth = 0.3) +
101+
ggplot2::theme_bw(base_size = base_size) +
102+
ggplot2::ggtitle(title_txt)
103+
if (!is.null(xlim_global)) {
104+
p <- p + ggplot2::coord_cartesian(xlim = xlim_global)
105+
}
106+
p
107+
}
108+
109+
# Split and plot (each panel is a separate plot; y only shows that group's parameters)
110+
plots <- list(
111+
Probabilities = mk_plot(dplyr::filter(df_melt, Group == "Probabilities"), "Probabilities"),
112+
Utilities = mk_plot(dplyr::filter(df_melt, Group == "Utilities"), "Utilities"),
113+
Costs = mk_plot(dplyr::filter(df_melt, Group == "Costs"), "Costs"),
114+
Other = mk_plot(dplyr::filter(df_melt, Group == "Other"), "Other")
115+
)
116+
117+
list(df_melt = df_melt, group_table = group_tab, plots = plots)
118+
}
119+

man/partsurv.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/prob_to_prob.Rd

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/rate_to_prob.Rd

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)