This is a ready-to-use checklist for reviewing a statistical program log, in SAS or R, as part of validation. A program that produced output is not the same as a program that ran clean, and the log is where the interpreter records the silent defects a compare can miss. Replace every <<FILL: ...>> placeholder, run it against both the production and validation program logs, and retain the completed checklist with the validation package. A filled specimen follows. This is general educational content to adapt, not regulatory advice.
Header
| Field | Entry |
|---|---|
| Study / protocol | <<FILL: study ID>> |
| Program name and version | <<FILL: program, version/commit>> |
| Output(s) produced | <<FILL: table/dataset ID>> |
| Language / environment | <<FILL: SAS 9.4 / R 4.x + package versions>> |
| Log file reference | <<FILL: retained log location>> |
| Reviewer | <<FILL: name>> |
How to use
Mark each item Pass, Fail, or N/A. Any Fail must be resolved or carry a documented “expected because” rationale before the program’s output is accepted. Automate the scan where possible: a utility that greps the log for the strings below and fails the run on a hit turns this checklist into an enforced gate rather than a manual habit.
Section A: SAS log
| # | Item | Pass/Fail/NA |
|---|---|---|
| A1 | No ERROR: messages remain in the log | <<FILL>> |
| A2 | No unexpected WARNING: messages (each remaining one justified) | <<FILL>> |
| A3 | No NOTE: MERGE statement has more than one data set with repeats of BY values (unintended many-to-many join) | <<FILL>> |
| A4 | No NOTE: Variable ... is uninitialized | <<FILL>> |
| A5 | No NOTE: Missing values were generated where a value was expected | <<FILL>> |
| A6 | No NOTE: Division by zero detected | <<FILL>> |
| A7 | No NOTE: ... values have been converted to (unintended character/numeric coercion) | <<FILL>> |
| A8 | No NOTE: ... 0 observations where rows were expected (empty join or subset) | <<FILL>> |
| A9 | Observation counts in key data steps match expectation | <<FILL>> |
| A10 | No invalid-data or NOTE: Invalid ... messages | <<FILL>> |
| A11 | Log is complete (not truncated) and corresponds to the delivered output version | <<FILL>> |
Section B: R session
| # | Item | Pass/Fail/NA |
|---|---|---|
| B1 | No errors; the script ran to completion | <<FILL>> |
| B2 | Warnings captured and reviewed; none unexpected (run configured to surface warnings) | <<FILL>> |
| B3 | No NA introduced by coercion where a value was expected (checked explicitly) | <<FILL>> |
| B4 | Join row counts confirmed against expectation (no silent many-to-many) | <<FILL>> |
| B5 | No unintended recycling or length-mismatch warnings | <<FILL>> |
| B6 | Session information (R version, key package versions) captured with the log | <<FILL>> |
| B7 | Output object dimensions match expectation (rows, columns, groups) | <<FILL>> |
Section C: both languages
| # | Item | Pass/Fail/NA |
|---|---|---|
| C1 | The log is retained with the program version and output as a record | <<FILL>> |
| C2 | Both the production and the validation program logs were reviewed | <<FILL>> |
| C3 | Every flagged message is resolved or carries a documented rationale | <<FILL>> |
| C4 | The reviewed log matches the version of the program that produced the delivered output | <<FILL>> |
References
ICH E6(R2), computerized-system and quality-control expectations. The independent programming SOP
<<FILL: SOP-ID>>.
Sign-off
| Role | Name | Signature | Date |
|---|---|---|---|
| Reviewer | <<FILL>> | ||
| Second reviewer (Tier 1, optional) | <<FILL>> |
Retention
Retain the completed checklist and the reviewed log with the validation package under the trial master file retention schedule, for not less than <<FILL: retention period>>.
Filled specimen
The following shows a partly completed review for a production ADaM program, so you can see how a real Fail is handled. Illustrative.
Header: Study ABC-301; program ADLB.sas v4 (commit 9f2a1); output ADLB dataset; SAS 9.4; reviewer M. Ruiz.
| # | Item | Result | Note |
|---|---|---|---|
| A1 | No ERROR messages | Pass | |
| A3 | No repeats-of-BY many-to-many note | Fail | Merge of ADLB with lookup produced the repeats note; join was unintentionally many-to-many on VISIT; fixed to include PARAMCD in the BY, reran clean |
| A4 | No uninitialized variable | Fail | BASE uninitialized for 6 subjects; derivation used study day 1 instead of dose datetime; corrected per SAP, reran |
| A5 | No unexpected missing generated | Pass | |
| A9 | Obs counts match expectation | Pass | 12,480 rows as expected after fix |
| C1 | Log retained with output | Pass |
In this example the log review caught a silent many-to-many merge and an uninitialized baseline variable, both of which had produced output that looked complete. The compare might have missed the baseline error if the QC sample happened to skip the six affected subjects. The log review found both in minutes, they were fixed against the SAP, and the program reran clean before the dataset was accepted.
Common inspection findings this checklist prevents
- A silent many-to-many merge that inflated row counts and values, shipped behind a clean-looking output.
- An uninitialized or coercion-generated missing value that shifted a derivation, undetected by record-level QC.
- Program logs not retained, so the run behind the delivered output cannot be examined.
- Only the production log reviewed, leaving the validation program’s own defects unchecked.
- Warnings dismissed with no rationale.
How to adapt this checklist
- Set your environment versions in the header; results can shift between SAS or R versions, so the version is part of the record.
- Keep the message strings current with your language version, and add any project-specific notes your standards treat as failures.
- Wire the string scan into your pipeline so a matching message fails the run automatically.
- Run it on both the production and validation logs, and confirm the retention period against your records schedule.