SAS TLF Pseudocode Library 217 TLF PROGRAMS

ADaM-based SAS pseudocode for every Table, Listing, and Figure in an early-phase clinical-pharmacology study — a complete, separate set per study design (parallel, crossover, single-sequence, SAD, MAD) plus the shared setup macros.

Status — illustrative pseudocode / skeleton, not validated software. These programs are spec / double-programming scaffolds, not validated production code. Nothing here originates a number: reported numbers come only from validated ADaM + double-programmed code per SOP, never from an LLM. All deliverables use participant (CDISC USUBJID/SUBJID preserved in code only).

ADaM-based SAS pseudocode for every Table, Listing, and Figure (TLF) in an early-phase clin-pharm study, with a complete separate set per study design. Illustrative structure for spec / double-programming — not validated production code. Reported numbers come from validated ADaM + double-programmed code per SOP; nothing here originates a number.

๐Ÿงฐ Before you start โ–ถ How to run ๐Ÿ“ Designs ๐Ÿ”ง How each program runs ๐Ÿ“‹ TLF inventory ๐Ÿ†˜ Troubleshooting ๐Ÿ’ป Browse the code

Before you start

You'll need: SAS 9.4+ (or SAS Studio) on a machine that can reach your study's CDISC ADaM datasets  ยท  the relevant ADaM tables for the TLF you're running โ€” at minimum ADSL, plus the domain the program reads (ADAE for AE tables, ADLB for labs, ADVS/ADEG for vitals/ECG, ADPC/ADPP for PK, ADPD for PD, ADIS for immunogenicity, ADEX for exposure)  ยท  write access to an output folder for the result datasets  ยท  the study's format catalog (treatment order, AE severity, lab ranges) referenced by %setup. No internet, no install beyond SAS itself. These are pseudocode skeletons โ€” open one, point a LIBNAME at your ADaM, and complete the spec; don't expect a clean run out of the box.

How to run a program

There's no single command-line driver โ€” each .sas is one self-contained TLF program. The pattern is the same for all 217: open it in SAS → point a LIBNAME at your ADaM → submit the program. Each program already %includes the shared macros and calls %setup / %designvars for you, so the two things you edit are the ADaM path and the output path in the %setup call near the top.

Quick-start checklist — click each as you finish it:

Run it

Either edit the %setup line inside the program and submit it directly, or drive it from a tiny wrapper that sets the libname and %includes the program. Both do the same thing:

/* --- run one TLF program from a wrapper (SAS 9.4+) --------------- */
libname adam "/data/cp101/adam" access=readonly;   /* your ADaM datasets   */
libname tfl  "/data/cp101/tfl";                     /* your output folder   */

/* submit a program from the folder for your study's design:               *
 *   parallel/  crossover/  single_sequence/  sad/  mad/                    */
%include "parallel/t_demographics.sas";   /* one program -> one output      */

/* โ€” or, equivalently, open parallel/t_demographics.sas in SAS, edit its    *
 *   %setup(study=CP-101, adam=/data/cp101/adam, out=/data/cp101/tfl);       *
 *   line to your paths, and just submit the whole program. โ€”               */
Each program's own header shows the canonical call sequence: %include "../00_setup_macros.sas"; then %setup(study=, adam=, out=); then %designvars(design=<folder>); then the TLF body. Run from the design folder (or adjust the relative ../ path to 00_setup_macros.sas). Reported numbers always come from validated ADaM + double-programmed code per SOP — never from this scaffold or an LLM.

Designs (one folder each — full set per design)

FolderDesignKey analysis differences
parallel/Parallel-groupBetween-group; treatment = TRT01A/TRT01AN
crossover/Crossover (2×2, Williams)Within-participant; by APERIOD/TRTSEQP; BE/ANOVA (mixed model, GMR + 90% CI)
single_sequence/Single-/fixed-sequence (e.g. DDI)By APERIOD; fixed order, no randomized sequence; ratio + 90% CI vs reference period
sad/Single Ascending DoseParallel cohorts (dose = treatment); dose-proportionality (power model)
mad/Multiple Ascending DoseParallel cohorts, repeated dosing; accumulation ratio (Rac), steady-state assessment

Design is also wired in code via %designvars(design=...) in 00_setup_macros.sas, so each design folder's programs differ only where the statistics genuinely differ (PK comparison, by-period/by-sequence safety, dose escalation) — Tables/Listings of safety are structurally identical, re-pointed to the design's treatment/period variables.

How each program runs

%include 00_setup_macros.sas → %setup → %designvars(design=<folder>) → TLF body (one program → one output)

TLF inventory (each = one program per design)

Disposition / Demographics / Exposure (ADSL, ADEX, ADCM, ADMH)

Safety — AE (ADAE)

Safety — Labs (ADLB)

Safety — Vitals / ECG (ADVS, ADEG)

PK (ADPC, ADPP)

PD / Biomarkers (ADPD)

Immunogenicity (ADIS)

Naming convention

t_ table · l_ listing · f_ figure. One program → one output. Each program %includes 00_setup_macros.sas, calls %setup then %designvars(design=<folder>), then the TLF body.

ADaM variables relied on (no re-derivation here)

Geometric PK statistics are computed on the log scale (never exp(arithmetic mean)). AE counts are distinct participants. Single-sequence participant-level tables key on &SEQVAR/&SEQVARN while period tables denominate from a period-bearing source. The library is free of eDISH / Hy's Law terminology.

Quality status

Complete: 217 TLF programs across all five design folders + 00_setup_macros.sas (218 files total). Built by fan-out generation, then a two-pass adversarial QC (6 family reviewers → per-finding verification: 35 confirmed defects fixed, 2 reviewer false-positives rejected), then a deterministic sweep. All programs scaffold correctly (%include/%setup/%designvars), %designvars matches each folder. Pseudocode for spec / double-programming — not validated production code; reported numbers still come from validated tools per SOP.

Troubleshooting

SymptomWhyFix
ERROR: Libref ADAM is not assigned / File ADAM.ADSL does not existThe LIBNAME in %setup doesn't point at your ADaM datasetsSet adam= in the %setup(...) call (or the wrapper libname adam) to the real folder holding ADSL/ADAE/…; it's opened access=readonly.
ERROR: Physical file does not exist … 00_setup_macros.sasThe program's %include "../00_setup_macros.sas" path is relative to where you submit fromSubmit from inside the design folder, or change the %include to the absolute path of 00_setup_macros.sas.
Columns/by-structure look wrong (e.g. no period split on a crossover)%designvars(design=...) doesn't match the folder you openedSet it to the folder's design: PARALLEL, CROSSOVER, SINGLESEQ, SAD, or MAD. It resolves &TRTVAR/&SEQVAR/&BYPERIOD.
ERROR: Format … not found in PROC REPORT/FORMATThe study format catalog (treatment order, AE severity, lab ranges) isn't available to %setupBuild/point tfl.formats at your study format catalog (the proc format library=tfl.formats step in 00_setup_macros.sas), then resubmit.
Geometric mean / Geo-CV% looks off vs the validated outputExpecting exp(arithmetic mean) — this library computes geo stats on the log scaleThat's intended: geo mean = exp(mean of logs), Geo-CV% = 100*sqrt(exp(var of logs)-1) (see %pkstats). Reconcile against the double-programmed value, not exp(mean).
AE counts higher than expectedTreating event rows as the unit instead of distinct participantsThe AE macros count count(distinct USUBJID) per level (treatment-emergent via TRTEMFL='Y'). Reconcile participant counts, not row counts.
Period table denominators don't add up (crossover / single-sequence)Denominating a per-period table from ADSL (one record per participant)Per-period denominators must come from a period-bearing source (ADEX/ADIS/ADPD); participant-level tables key on &SEQVAR/&SEQVARN.
Looking for an eDISH / Hy's-Law panelThe library deliberately omits that terminologyUse f_lab_lft_scatter.sas + the lab tables for transaminase/bilirubin review; there is no eDISH/Hy's Law output by design.

Every program is a spec / double-programming scaffold, not validated production code. If a number here disagrees with the validated, double-programmed result, the validated result governs — always reconcile per SOP.

Browse the code

Every program below links to its actual .sas file by relative path. Start with the shared macros, then pick a design folder.

Shared setup

00_setup_macros.sas%setup + %designvars; included by every program

parallel/ PARALLEL-GROUP

Disposition / Demographics / Exposure

t_disposition.sas t_demographics.sas t_baseline_characteristics.sas t_exposure.sas t_protocol_deviations.sas t_prior_con_meds.sas t_medical_history.sas l_disposition.sas

Safety — AE

t_ae_overview.sas t_ae_by_soc_pt.sas t_ae_by_severity.sas t_ae_by_relationship.sas t_ae_sae_death_withdrawal.sas l_ae.sas l_sae_death.sas

Safety — Labs

t_lab_summary.sas t_lab_shift.sas t_lab_marked_abnormal.sas f_lab_lft_scatter.sas f_lab_change.sas l_lab_abnormal.sas

Vitals / ECG

t_vitals_summary.sas f_vitals_change.sas l_vitals.sas t_ecg_summary.sas t_ecg_qtc_categorical.sas f_qtc_change.sas l_ecg.sas

PK

t_pk_conc_summary.sas l_pk_conc.sas f_pk_conc_mean.sas f_pk_conc_individual.sas t_pk_param_summary.sas l_pk_param.sas f_pk_param_boxplot.sas

PD / Biomarkers

t_pd_summary.sas f_pd_change.sas f_pkpd_overlay.sas l_pd.sas

Immunogenicity

t_ada_summary.sas t_ada_impact_pk.sas l_ada.sas

crossover/ 2×2 / WILLIAMS

Disposition / Demographics / Exposure

t_disposition.sas t_demographics.sas t_baseline_characteristics.sas t_exposure.sas t_protocol_deviations.sas t_prior_con_meds.sas t_medical_history.sas l_disposition.sas

Safety — AE

t_ae_overview.sas t_ae_by_soc_pt.sas t_ae_by_severity.sas t_ae_by_relationship.sas t_ae_sae_death_withdrawal.sas l_ae.sas l_sae_death.sas

Safety — Labs

t_lab_summary.sas t_lab_shift.sas t_lab_marked_abnormal.sas f_lab_lft_scatter.sas f_lab_change.sas l_lab_abnormal.sas

Vitals / ECG

t_vitals_summary.sas f_vitals_change.sas l_vitals.sas t_ecg_summary.sas t_ecg_qtc_categorical.sas f_qtc_change.sas l_ecg.sas

PK (incl. t_be_anova, t_pk_param_by_period)

t_pk_conc_summary.sas l_pk_conc.sas f_pk_conc_mean.sas f_pk_conc_individual.sas t_pk_param_summary.sas t_pk_param_by_period.sas l_pk_param.sas f_pk_param_boxplot.sas t_be_anova.sasBE/ANOVA mixed model, GMR + 90% CI

PD / Biomarkers

t_pd_summary.sas f_pd_change.sas f_pkpd_overlay.sas l_pd.sas

Immunogenicity

t_ada_summary.sas t_ada_impact_pk.sas l_ada.sas

single_sequence/ FIXED-SEQUENCE / DDI

Disposition / Demographics / Exposure

t_disposition.sas t_demographics.sas t_baseline_characteristics.sas t_exposure.sas t_protocol_deviations.sas t_prior_con_meds.sas t_medical_history.sas l_disposition.sas

Safety — AE

t_ae_overview.sas t_ae_by_soc_pt.sas t_ae_by_severity.sas t_ae_by_relationship.sas t_ae_sae_death_withdrawal.sas l_ae.sas l_sae_death.sas

Safety — Labs

t_lab_summary.sas t_lab_shift.sas t_lab_marked_abnormal.sas f_lab_lft_scatter.sas f_lab_change.sas l_lab_abnormal.sas

Vitals / ECG

t_vitals_summary.sas f_vitals_change.sas l_vitals.sas t_ecg_summary.sas t_ecg_qtc_categorical.sas f_qtc_change.sas l_ecg.sas

PK (incl. t_be_anova ratio + 90% CI vs reference period, t_pk_param_by_period)

t_pk_conc_summary.sas l_pk_conc.sas f_pk_conc_mean.sas f_pk_conc_individual.sas t_pk_param_summary.sas t_pk_param_by_period.sas l_pk_param.sas f_pk_param_boxplot.sas t_be_anova.sasRatio + 90% CI vs reference period

PD / Biomarkers

t_pd_summary.sas f_pd_change.sas f_pkpd_overlay.sas l_pd.sas

Immunogenicity

t_ada_summary.sas t_ada_impact_pk.sas l_ada.sas

sad/ SINGLE ASCENDING DOSE

Disposition / Demographics / Exposure

t_disposition.sas t_demographics.sas t_baseline_characteristics.sas t_exposure.sas t_protocol_deviations.sas t_prior_con_meds.sas t_medical_history.sas l_disposition.sas

Safety — AE

t_ae_overview.sas t_ae_by_soc_pt.sas t_ae_by_severity.sas t_ae_by_relationship.sas t_ae_sae_death_withdrawal.sas l_ae.sas l_sae_death.sas

Safety — Labs

t_lab_summary.sas t_lab_shift.sas t_lab_marked_abnormal.sas f_lab_lft_scatter.sas f_lab_change.sas l_lab_abnormal.sas

Vitals / ECG

t_vitals_summary.sas f_vitals_change.sas l_vitals.sas t_ecg_summary.sas t_ecg_qtc_categorical.sas f_qtc_change.sas l_ecg.sas

PK (incl. t_dose_proportionality power model)

t_pk_conc_summary.sas l_pk_conc.sas f_pk_conc_mean.sas f_pk_conc_individual.sas t_pk_param_summary.sas l_pk_param.sas f_pk_param_boxplot.sas t_dose_proportionality.sasPower model

PD / Biomarkers

t_pd_summary.sas f_pd_change.sas f_pkpd_overlay.sas l_pd.sas

Immunogenicity

t_ada_summary.sas t_ada_impact_pk.sas l_ada.sas

mad/ MULTIPLE ASCENDING DOSE

Disposition / Demographics / Exposure

t_disposition.sas t_demographics.sas t_baseline_characteristics.sas t_exposure.sas t_protocol_deviations.sas t_prior_con_meds.sas t_medical_history.sas l_disposition.sas

Safety — AE

t_ae_overview.sas t_ae_by_soc_pt.sas t_ae_by_severity.sas t_ae_by_relationship.sas t_ae_sae_death_withdrawal.sas l_ae.sas l_sae_death.sas

Safety — Labs

t_lab_summary.sas t_lab_shift.sas t_lab_marked_abnormal.sas f_lab_lft_scatter.sas f_lab_change.sas l_lab_abnormal.sas

Vitals / ECG

t_vitals_summary.sas f_vitals_change.sas l_vitals.sas t_ecg_summary.sas t_ecg_qtc_categorical.sas f_qtc_change.sas l_ecg.sas

PK (incl. t_accumulation Rac / steady-state, t_dose_proportionality_ss)

t_pk_conc_summary.sas l_pk_conc.sas f_pk_conc_mean.sas f_pk_conc_individual.sas t_pk_param_summary.sas l_pk_param.sas f_pk_param_boxplot.sas t_accumulation.sasAccumulation ratio (Rac), steady-state t_dose_proportionality_ss.sasDose-proportionality at steady state

PD / Biomarkers

t_pd_summary.sas f_pd_change.sas f_pkpd_overlay.sas l_pd.sas

Immunogenicity

t_ada_summary.sas t_ada_impact_pk.sas l_ada.sas