Tables, Listings & Figures with rtables, tern & gtsummary
Producing regulated TLF outputs from analysis datasets.
Learning objectives
- 1Build demographic and AE summary tables using industry-standard frameworks.
- 2Compare gtsummary (rapid) vs rtables/tern (submission-grade control).
- 3Create publication-quality figures with ggplot2 + themes.
- 4Export tables and figures to RTF/PDF suitable for eCTD appendices.
Key SAS® → R comparison
| Task | SAS® | R |
|---|---|---|
| Demographics table | PROC REPORT + ODS | gtsummary or tern::demog_tbl |
| AE incidence | PROC FREQ + custom macro | tern::count_occurrences |
| Shift / lab tables | Complex PROC REPORT | tern + rtables layout |
| Figures | PROC SGPLOT / GTL | ggplot2 + ggsurvfit / ggpubr |
| Regulatory export | ODS RTF + styles | rtables::export_as_rtf + r2rtf |
Code examples
proc report data=adsl;
columns arm age sex;
define arm / group;
...
run;library(gtsummary)
adsl |>
select(ARM, AGE, SEX, RACE, BMIBL) |>
tbl_summary(
by = ARM,
statistic = list(all_continuous() ~ "{mean} ({sd})"),
digits = all_continuous() ~ 1
) |>
add_p() |>
add_overall() |>
modify_header(label ~ "**Characteristic**")Note: gtsummary is perfect for internal reports and many standard tables. For formal CSR TLFs many sponsors still prefer rtables for pixel-perfect control.
/* Custom %ae_table macro with 20+ parameters */
%ae_table(data=adae, by=trt01a, ...);adae |>
count_occurrences(
variables = exprs(AEBODSYS, AEDECOD),
by = ARM
) |>
add_overall(across = "col") |>
build_table()Note: tern's count_occurrences + risk tables give you exactly the structure regulators expect with far less custom code than traditional SAS macros.
proc sgplot data=adlb;
series x=avisitn y=meanchg / group=arm;
...
run;ggplot(adlb_mean, aes(x = AVISITN, y = mean_chg, color = ARM)) +
geom_line(linewidth = 1) +
geom_point(size = 2.5) +
labs(title = "Mean Change in Systolic BP",
x = "Visit", y = "Change from Baseline (mmHg)") +
theme_classic() +
scale_color_brewer(palette = "Set1")Note: ggplot2 figures can be saved at 300 dpi for submission or converted to editable EMF via the officer or rvg packages.
Explanation
The TLF ecosystem in R is now mature enough for real regulatory submissions. gtsummary excels at speed and attractive defaults for exploratory work and many standard outputs. For the tightly controlled, highly formatted tables required in a CSR or ISS/ISE, rtables + tern give you the same level of layout precision that experienced SAS programmers achieve with PROC REPORT and ODS.
Figures are almost universally moving to ggplot2 because the grammar is vastly more powerful and the theming system produces consistent branding across a submission with almost no per-figure tweaking.
Export tooling (r2rtf, rtables exporters, officer for Word) closes the loop so your final deliverables can be dropped straight into the eCTD without manual reformatting.