| Title: | Efficacy and Safety Graphics for Clinical Review Packages |
| Version: | 0.1.0 |
| Description: | Builds submission-style efficacy and safety figures used in clinical review packages, with one simulator for each therapeutic area. Oncology figures include Kaplan-Meier curves, RECIST waterfalls, swimmer plots and spider plots. Cardiovascular, endocrine, immunology, infectious disease and neuroscience figures include time-to-event curves, mean change from baseline and responder rates. Shared safety figures include an adverse-event dot plot, an eDISH liver plot, a laboratory shift plot and an exposure plot. Reference lines follow RECIST 1.1 and the FDA drug-induced liver injury guidance. This is not an FDA product and does not guarantee regulatory acceptance. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| Imports: | ggplot2, survival, withr |
| Suggests: | testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| Language: | en-US |
| URL: | https://github.com/shekharchalwadigrepo-hub/trialfigs |
| BugReports: | https://github.com/shekharchalwadigrepo-hub/trialfigs/issues |
| RoxygenNote: | 7.3.2 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-03 04:34:55 UTC; skrch |
| Author: | Shekhar [aut, cre] |
| Maintainer: | Shekhar <skrchalwadicg@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-15 15:50:02 UTC |
Efficacy and safety graphics for clinical review packages
Description
Simulated-data utilities and submission-style figures commonly used in
clinical review packages. Not an FDA product. See ta_plot_catalog
for the therapeutic-area map.
Author(s)
Shekhar
See Also
plot_km, plot_waterfall, plot_edish
Cox hazard ratio with the investigational arm in the numerator
Description
The reference level is the other arm, so a ratio below 1 favours the investigational arm. One row is returned, for binding into a forest.
Usage
cox_hr(data, time, event, arm, investigational = "Investigational",
subgroup = "Overall")
Arguments
data |
Subject-level data. |
time, event, arm |
Column names. |
investigational |
Level of |
subgroup |
Label stored in the result. |
Value
A one-row data frame with subgroup, estimate, limits and n.
Examples
onc <- simulate_oncology(n_per_arm = 20)
cox_hr(onc$adsl, "os_months", "os_event", "arm")
Color palette for review figures
Description
Named colors for treatment arms and RECIST responses.
Usage
fda_palette()
Value
A named character vector of colors.
Examples
fda_palette()
Theme for review figures
Description
Classic theme with a left-aligned caption for population notes.
Usage
fda_theme(base_size = 11)
Arguments
base_size |
Base font size in points. |
Value
A ggplot2 theme object.
Examples
fda_theme()
Adverse-event incidence dot plot
Description
Percent of subjects with each term and a Wilson interval, ordered by the risk difference versus the reference arm.
Usage
plot_ae(data, term = "term", arm = "arm", denom = NULL, id = "usubjid",
reference = "Placebo", title = "Subjects with an adverse event")
Arguments
data |
One row per subject per event. |
term, arm, id |
Column names. |
denom |
Subject-level denominator. Required for a correct percent. |
reference |
Arm used when ordering by risk difference. |
title |
Plot title. |
Value
A ggplot object.
Examples
saf <- simulate_safety(n_per_arm = 25)
plot_ae(saf$adae, denom = saf$adsl, reference = "Placebo")
Mean change from baseline with a confidence interval
Description
The band is the normal approximation to the standard error of the mean. Replace it with the model named in the statistical analysis plan for a primary contrast.
Usage
plot_change(data, visit = "week", change = "chg", arm = "arm",
title = "Mean change from baseline", xlab = "Week",
ylab = "Mean change (95% CI)")
Arguments
data |
Longitudinal data. |
visit, change, arm |
Column names. |
title, xlab, ylab |
Labels. |
Value
A ggplot object.
Examples
endo <- simulate_endocrinology(n_per_arm = 15)
plot_change(endo$adlb, title = "HbA1c")
eDISH plot of peak ALT versus peak bilirubin
Description
Log-scale multiples of the upper limit of normal. Reference lines are ALT 3x ULN and total bilirubin 2x ULN. A point in that quadrant needs narrative review; it is not by itself a Hy's law case.
Usage
plot_edish(data, alt = "alt_xuln", bili = "bili_xuln", arm = "arm",
id = "usubjid", title = "eDISH: peak ALT vs peak total bilirubin")
Arguments
data |
One row per subject, peak values. |
alt, bili, arm |
Column names, values in multiples of ULN. |
id |
Optional subject id, labelled for quadrant cases. |
title |
Plot title. |
Value
A ggplot object.
Examples
saf <- simulate_safety(n_per_arm = 25)
plot_edish(saf$adlb)
Treatment duration by arm
Description
Box plot of exposure with the median in the caption.
Usage
plot_exposure(data, duration = "trtdur_days", arm = "arm",
xlab = "Treatment duration (days)", title = "Exposure")
Arguments
data |
Subject-level data. |
duration, arm |
Column names. |
xlab, title |
Labels. |
Value
A ggplot object.
Examples
saf <- simulate_safety(n_per_arm = 20)
plot_exposure(saf$adsl)
Forest plot of a ratio or a difference
Description
Use null = 1 for hazard ratios and null = 0 for mean differences.
Intervals that cross the null are drawn in grey.
Usage
plot_forest(data, label = "subgroup", estimate = "estimate", lcl = "lcl",
ucl = "ucl", n = NULL, null = 1, xlab = "Hazard ratio (95% CI)",
title = "Subgroup forest plot", subtitle = NULL,
favour_left = "Favours investigational",
favour_right = "Favours control")
Arguments
data |
One row per subgroup or endpoint. |
label, estimate, lcl, ucl |
Column names. |
n |
Optional sample-size column. |
null |
Null value drawn as a vertical line. |
xlab, title, subtitle, favour_left, favour_right |
Labels. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 20)
forest <- cox_hr(onc$adsl, "os_months", "os_event", "arm")
plot_forest(forest)
Kaplan-Meier curve with number at risk
Description
Event-free curve with censoring ticks, dashed confidence limits, a log-rank p-value and the number at risk. Competing risks are not modelled.
Usage
plot_km(data, time, event, arm, xlab = "Time (months)",
ylab = "Event-free probability", title = "Kaplan-Meier estimate",
subtitle = NULL, conf_int = TRUE, risk_times = NULL, palette = NULL,
population = "Intent-to-treat population")
Arguments
data |
Subject-level data. |
time, event, arm |
Column names. |
xlab, ylab, title, subtitle |
Labels. |
conf_int |
Draw pointwise confidence limits. |
risk_times |
Times for the number at risk. Default is |
palette |
Named color vector. |
population |
Analysis-population note printed in the caption. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 15)
plot_km(onc$adsl, time = "os_months", event = "os_event", arm = "arm")
Baseline versus post-baseline maximum
Description
Points above the identity line rose after baseline.
Usage
plot_lab_shift(data, baseline = "alt_base", post = "alt_max", arm = "arm",
uln = NULL, title = "Baseline vs post-baseline maximum",
xlab = "Baseline", ylab = "Post-baseline maximum")
Arguments
data |
One row per subject. |
baseline, post, arm |
Column names. |
uln |
Upper limit of normal, drawn if not NULL. |
title, xlab, ylab |
Labels. |
Value
A ggplot object.
Examples
saf <- simulate_safety(n_per_arm = 20)
plot_lab_shift(saf$adlb, uln = 1)
Binary responder rate with a Wilson interval
Description
Percent of responders by arm, with a Wilson score interval.
Usage
plot_responder(data, responder, arm, title = "Responder rate",
ylab = "Responders, percent (Wilson 95% CI)")
Arguments
data |
Subject-level data. |
responder |
Logical or 0/1 column name. |
arm |
Arm column name. |
title, ylab |
Labels. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 15)
onc$adsl$responder <- onc$adsl$bor %in% c("CR", "PR")
plot_responder(onc$adsl, responder = "responder", arm = "arm")
Spider plot of percent change over time
Description
Individual tumor trajectories with the arm mean overlaid.
Usage
plot_spider(data, id = "usubjid", time = "week", pct = "pct_change",
arm = "arm", title = "Percent change in sum of diameters")
Arguments
data |
Longitudinal data, one row per subject per visit. |
id, time, pct, arm |
Column names. |
title |
Plot title. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 8)
plot_spider(onc$adtr)
Swimmer plot of time on treatment
Description
One bar per subject, with points for objective response and progression. Limited to the longest durations so the figure stays readable.
Usage
plot_swimmer(data, id = "usubjid", arm = "arm",
duration = "trtdur_months", response_time = "resp_months",
progression_time = "pd_months", max_n = 30, xlab = "Months",
title = "Time on treatment")
Arguments
data |
Subject-level data. |
id, arm, duration |
Column names. |
response_time, progression_time |
Optional column names. |
max_n |
Maximum subjects, taken as the longest durations. |
xlab, title |
Labels. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 12)
plot_swimmer(onc$adsl, max_n = 10)
RECIST waterfall of best percent change
Description
Bars of best percent change in the sum of diameters. Reference lines at -30 and +20 follow RECIST 1.1. Subjects with no post-baseline value are omitted.
Usage
plot_waterfall(data, pct = "pct_change", response = "bor", arm = "arm",
id = "usubjid", title = "Best percent change in sum of diameters",
subtitle = "RECIST 1.1 reference lines at -30% and +20%",
palette = NULL)
Arguments
data |
Subject-level data. |
pct, response, arm, id |
Column names. |
title, subtitle |
Labels. |
palette |
Named colors for response categories. |
Value
A ggplot object.
Examples
onc <- simulate_oncology(n_per_arm = 15)
plot_waterfall(onc$adsl)
Simulate a cardiovascular outcomes set
Description
Time to first MACE and systolic blood pressure. Synthetic data.
Usage
simulate_cardiovascular(n_per_arm = 220, seed = 20260316)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and advs.
Examples
cv <- simulate_cardiovascular(n_per_arm = 20)
plot_km(cv$adsl, time = "mace_months", event = "mace_event", arm = "arm")
Simulate a type 2 diabetes HbA1c set
Description
Longitudinal HbA1c. Synthetic data.
Usage
simulate_endocrinology(n_per_arm = 150, seed = 20260317)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and adlb.
Examples
endo <- simulate_endocrinology(n_per_arm = 15)
plot_change(endo$adlb)
Simulate a rheumatoid-arthritis DAS28 set
Description
Longitudinal DAS28. Synthetic data.
Usage
simulate_immunology(n_per_arm = 120, seed = 20260318)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and adeff.
Examples
imm <- simulate_immunology(n_per_arm = 15)
plot_change(imm$adeff, title = "DAS28")
Simulate an antiviral viral-load set
Description
Log10 viral load and time to clearance. Synthetic data.
Usage
simulate_infectious(n_per_arm = 100, seed = 20260319)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and adlb.
Examples
id <- simulate_infectious(n_per_arm = 15)
plot_change(id$adlb, visit = "day", xlab = "Day")
Simulate a depression MADRS set
Description
Longitudinal MADRS. Synthetic data.
Usage
simulate_neuroscience(n_per_arm = 140, seed = 20260320)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and adeff.
Examples
cns <- simulate_neuroscience(n_per_arm = 15)
plot_change(cns$adeff, title = "MADRS")
Simulate a two-arm oncology efficacy set
Description
Subject-level survival, RECIST response, and longitudinal tumor measurements. Data are synthetic. The random-number stream is restored on exit.
Usage
simulate_oncology(n_per_arm = 80, seed = 20260315)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl and adtr.
Examples
onc <- simulate_oncology(n_per_arm = 10)
plot_waterfall(onc$adsl)
Simulate core safety data
Description
Adverse events and peak liver tests in multiples of the upper limit of normal. Synthetic data.
Usage
simulate_safety(n_per_arm = 160, seed = 20260321)
Arguments
n_per_arm |
Subjects per arm. |
seed |
Random seed, restored after the call. |
Value
A list with adsl, adae and adlb.
Examples
saf <- simulate_safety(n_per_arm = 20)
plot_edish(saf$adlb)
Recommended displays by therapeutic area
Description
Working catalog of figures commonly discussed in a clinical review. Not a regulatory requirement.
Usage
ta_plot_catalog()
Value
A data frame with therapeutic area, display, function name and anchor.
Examples
head(ta_plot_catalog())