184.HOW TO CREATE MOCK SHELLS AND CLINICAL DATA LISTINGS IN SAS USING DATA NULL | PROC PRINT | PROC REPORT | PROC SORT | PROC COMPARE | ODS PDF | ODS RTF | ODS EXCEL | A COMPLETE STEP-BY-STEP GUIDE FOR CLINICAL SAS PROGRAMMERS
- Get link
- X
- Other Apps
HOW TO CREATE MOCK SHELLS AND CLINICAL DATA LISTINGS IN SAS USING DATA NULL | PROC PRINT | PROC REPORT | PROC SORT | PROC COMPARE | ODS PDF | ODS RTF | ODS EXCEL | A COMPLETE STEP-BY-STEP GUIDE FOR CLINICAL SAS PROGRAMMERS
/*Creating mock shells and listings in SAS is a critical part of clinical programming.
These are used to present clinical trial data in a standardized, readable, and
review-ready format.*/
What is a Listing?
A listing is a detailed tabular report of subject-level clinical trial data (raw or SDTM/ADaM), generally created to:
Allow medical reviewers and statisticians to review patient data.
Support analysis results by providing traceability.
Comply with FDA or other regulatory submissions.
Listings are typically derived from SDTM or ADaM datasets, especially:
ADSL (Subject-Level Analysis Dataset)
ADAE (Adverse Events)
ADLB (Lab Data)
ADVS (Vital Signs)
Step-by-Step Guide to Create a Mock Shell and Listing in SAS
Step 1: Simulate or Use Existing Data
We will create a mock dataset that mimics ADAE (Adverse Events).
data adae;
input usubjid $ aeseq aedecod $ aebodsys: $18. astdtc : yymmdd10. aendtc : yymmdd10.
aesev $ aerel $ aetrtem $;
format astdtc aendtc yymmdd10.;
datalines;
1001 1 Headache Nervous 2023-01-01 2023-01-03 Mild Related Yes
1001 2 Nausea Gastrointestinal 2023-01-05 2023-01-07 Moderate Not Related No
1002 1 Dizziness Nervous 2023-01-02 2023-01-04 Severe Related Yes
1003 1 Vomiting Gastrointestinal 2023-01-10 2023-01-12 Mild Related No
1004 1 Rash Skin 2023-01-15 2023-01-17 Moderate Possibly Related Yes
;
run;
proc print;run;
Output:
Obs | usubjid | aeseq | aedecod | aebodsys | astdtc | aendtc | aesev | aerel | aetrtem |
---|---|---|---|---|---|---|---|---|---|
1 | 1001 | 1 | Headache | Nervous | 2023-01-01 | 2023-01-03 | Mild | Related | Yes |
2 | 1001 | 2 | Nausea | Gastrointestinal | 2023-01-05 | 2023-01-07 | Moderate | Not | Related |
3 | 1002 | 1 | Dizzines | Nervous | 2023-01-02 | 2023-01-04 | Severe | Related | Yes |
4 | 1003 | 1 | Vomiting | Gastrointestinal | 2023-01-10 | 2023-01-12 | Mild | Related | No |
5 | 1004 | 1 | Rash | Skin | 2023-01-15 | 2023-01-17 | Moderate | Possibly | Related |
Step 2: Create a Mock Shell (Using DATA _NULL_)
You can print a mock shell without displaying real data using DATA _NULL_ or a macro template.
data _null_;
file print;
put "Listing 1.1";
put "Adverse Events Listing";
put 80*'-';
put 'Subject | Seq | AE Term | System Organ Class | Start Date | End Date
| Severity | Related | Treatment Emergent';
put 80*'-';
put 'xxxxxxx | xxx | xxxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxMMMYYYY | xxMMMYYYY
| xxxxxxxx | xxxxxxx | xxxxxxxxxxxxxxxxxx';
put 80*'-';
put 'Note: AE = Adverse Event';
run;
Output:
Step 3: Generate Actual Listing using PROC PRINT
proc print data=adae noobs label;
title "Listing 1.1";
title2 "Adverse Events by Subject";
var usubjid aeseq aedecod aebodsys astdtc aendtc aesev aerel aetrtem;
label
usubjid = "Subject ID"
aeseq = "AE Sequence"
aedecod = "Adverse Event"
aebodsys = "System Organ Class"
astdtc = "Start Date"
aendtc = "End Date"
aesev = "Severity"
aerel = "Related to Drug"
aetrtem = "Treatment Emergent";
run;
Output:
Listing 1.1 |
Adverse Events by Subject |
Subject ID | AE Sequence | Adverse Event | System Organ Class | Start Date | End Date | Severity | Related to Drug | Treatment Emergent |
---|---|---|---|---|---|---|---|---|
1001 | 1 | Headache | Nervous | 2023-01-01 | 2023-01-03 | Mild | Related | Yes |
1001 | 2 | Nausea | Gastrointestinal | 2023-01-05 | 2023-01-07 | Moderate | Not | Related |
1002 | 1 | Dizzines | Nervous | 2023-01-02 | 2023-01-04 | Severe | Related | Yes |
1003 | 1 | Vomiting | Gastrointestinal | 2023-01-10 | 2023-01-12 | Mild | Related | No |
1004 | 1 | Rash | Skin | 2023-01-15 | 2023-01-17 | Moderate | Possibly | Related |
Step 4: Enhance Listing Using PROC REPORT
PROC REPORT allows better control of styling, headers, and grouping.
ods rtf file="adae_listing.rtf" style=journal;
proc report data=adae nowd;
column usubjid aeseq aedecod aebodsys astdtc aendtc aesev aerel aetrtem;
define usubjid / group "Subject ID";
define aeseq / display "AE Seq";
define aedecod / display "AE Term";
define aebodsys / display "System Organ Class";
define astdtc / display "Start Date";
define aendtc / display "End Date";
define aesev / display "Severity";
define aerel / display "Related to Drug";
define aetrtem / display "Treatment Emergent";
compute after usubjid;
line " ";
endcomp;
run;
ods rtf close;
Step 5: Add Footnotes and Headers
title1 "Listing 1.1";
title2 "Subject-Level Adverse Events Listing";
footnote1 "Note: AE = Adverse Event";
footnote2 "Source: ADAE Analysis Dataset";
Output:
Listing 1.1 |
Subject-Level Adverse Events Listing |
Subject ID | AE Seq | AE Term | System Organ Class | Start Date | End Date | Severity | Related to Drug | Treatment Emergent |
---|---|---|---|---|---|---|---|---|
1001 | 1 | Headache | Nervous | 2023-01-01 | 2023-01-03 | Mild | Related | Yes |
2 | Nausea | Gastrointestinal | 2023-01-05 | 2023-01-07 | Moderate | Not | Related | |
1002 | 1 | Dizzines | Nervous | 2023-01-02 | 2023-01-04 | Severe | Related | Yes |
1003 | 1 | Vomiting | Gastrointestinal | 2023-01-10 | 2023-01-12 | Mild | Related | No |
1004 | 1 | Rash | Skin | 2023-01-15 | 2023-01-17 | Moderate | Possibly | Related |
Note: AE = Adverse Event |
Source: ADAE Analysis Dataset |
Step 6: Use Macros for Reusability
%macro listing(ds=, vars=, labels=, title=, file=);
ods rtf file="&file..rtf" style=journal;
title "&title";
proc report data=&ds nowd;
column &vars;
%let i = 1;
%do %while(%scan(&vars, &i) ne );
%let var = %scan(&vars, &i);
%let lbl = %scan(&labels, &i);
define &var / display "&lbl";
%let i = %eval(&i + 1);
%end;
run;
ods rtf close;
%mend;
%listing(
ds=adae,
vars=usubjid aeseq aedecod aebodsys astdtc aendtc aesev aerel aetrt,
labels=Subject_ID AE_Seq AE_Term System_Organ_Class Start_Date End_Date Severity Related Treatment_Emergent,
title=Adverse Events Listing,
file=adae_listing
);
Output:
|
Step 7: Best Practices for Listings
proc sort data=adae;
by usubjid aeseq;
run;
proc print;run;
Output:
Obs | usubjid | aeseq | aedecod | aebodsys | astdtc | aendtc | aesev | aerel | aetrtem |
---|---|---|---|---|---|---|---|---|---|
1 | 1001 | 1 | Headache | Nervous | 2023-01-01 | 2023-01-03 | Mild | Related | Yes |
2 | 1001 | 2 | Nausea | Gastrointestinal | 2023-01-05 | 2023-01-07 | Moderate | Not | Related |
3 | 1002 | 1 | Dizzines | Nervous | 2023-01-02 | 2023-01-04 | Severe | Related | Yes |
4 | 1003 | 1 | Vomiting | Gastrointestinal | 2023-01-10 | 2023-01-12 | Mild | Related | No |
5 | 1004 | 1 | Rash | Skin | 2023-01-15 | 2023-01-17 | Moderate | Possibly | Related |
Ensure consistent date formats using YYMMDD10., DATE9., or ISO format.
Use SASHELP.STYLE options to pick journal-specific formats.
Always include footnotes, source lines, and explanatory notes.
Step 8: Export Listing to PDF, Excel, or RTF
ods pdf file="listing1_adae.pdf";
* Your PROC PRINT or REPORT code;
ods pdf close;
ods excel file="listing1_adae.xlsx";
* Your PROC PRINT or REPORT code;
ods excel close;
Step 9: Validation and QC Checks
Confirm usubjid, aeseq, and date ranges are valid.
Check for missing values in critical variables.
Review derived variables like treatment emergent flags (aetrtem).
Perform double programming or compare results using:
proc compare base=listing1 target=listing2;
run;
- Get link
- X
- Other Apps
Comments
Post a Comment