This report demonstrates the visit_tracker
SAS macro for operational monitoring of longitudinal studies. The macro creates expected schedules of participant visits, applies visit windows, matches actual to expected visits, and summarizes completion and retention metrics. Each example below uses synthetic data to showcase a different scheduling logic or windowing rule.
Example 1 — Semiannual (18 months)
Example 2 — Dense early
Example 3 — LOOKUP + custom order
Example 4 — LAG windows
Example 5 — Weekly
Summary and Next Steps
In this example, participants are expected every 6 months (baseline, 6m, 12m, 18m).
A fixed 90-day window after each target date allows visits to be considered valid if late.
This mimics a classic longitudinal cohort with semiannual follow-up.
Obs | Participant ID | Site ID | visit_ord | Scheduled Visit | Target Date | Visit Window Start | Visit Window End | Actual Visit Date | Difference (Actual - Target, Days) | Visit Status (On-Time/Early/Late/Missed) |
---|---|---|---|---|---|---|---|---|---|---|
1 | P001 | 1 | 0 | V0 | 23SEP2024 | 23SEP2024 | 22DEC2024 | 24SEP2024 | 1 | LATE |
2 | P001 | 1 | 180 | V180 | 22MAR2025 | 22MAR2025 | 20JUN2025 | 24MAR2025 | 2 | LATE |
3 | P001 | 1 | 360 | V360 | 18SEP2025 | 18SEP2025 | 17DEC2025 | 08OCT2025 | 20 | LATE |
4 | P001 | 1 | 540 | V540 | 17MAR2026 | 17MAR2026 | 15JUN2026 | 23MAR2026 | 6 | LATE |
5 | P002 | 1 | 0 | V0 | 13OCT2024 | 13OCT2024 | 11JAN2025 | . | . | MISSED |
6 | P002 | 1 | 180 | V180 | 11APR2025 | 11APR2025 | 10JUL2025 | . | . | MISSED |
7 | P002 | 1 | 360 | V360 | 08OCT2025 | 08OCT2025 | 06JAN2026 | 13NOV2025 | 36 | LATE |
8 | P002 | 1 | 540 | V540 | 06APR2026 | 06APR2026 | 05JUL2026 | 06APR2026 | 0 | ON_TIME |
9 | P003 | 1 | 0 | V0 | 26SEP2024 | 26SEP2024 | 25DEC2024 | 01OCT2024 | 5 | LATE |
10 | P003 | 1 | 180 | V180 | 25MAR2025 | 25MAR2025 | 23JUN2025 | . | . | MISSED |
Obs | Participant ID | Site ID | Visit Label | Baseline Date | Actual Visit Date (Unmatched) |
---|---|---|---|---|---|
1 | P001 | 1 | UNSCHED | 23SEP2024 | 04JUL2025 |
2 | P002 | 1 | V10 | 13OCT2024 | 01OCT2024 |
3 | P003 | 1 | V20 | 26SEP2024 | 15MAR2025 |
4 | P004 | 1 | V20 | 08SEP2024 | 26FEB2025 |
5 | P004 | 1 | V40 | 08SEP2024 | 21FEB2026 |
6 | P005 | 1 | UNSCHED | 22SEP2024 | 19FEB2025 |
7 | P005 | 1 | V30 | 22SEP2024 | 03SEP2025 |
8 | P005 | 1 | V40 | 22SEP2024 | 18FEB2026 |
9 | P006 | 1 | V10 | 01SEP2024 | 25AUG2024 |
10 | P006 | 1 | UNSCHED | 01SEP2024 | 16FEB2025 |
Obs | Visit Order (days from Baseline) | Scheduled Visit | Site ID | On-Time | Early | Late | Missed | Total Expected | Completion Rate (%) |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | V0 | 1 | 1 | 0 | 5 | 4 | 10 | 60.0% |
2 | 0 | V0 | 2 | 0 | 0 | 3 | 7 | 10 | 30.0% |
3 | 180 | V180 | 1 | 0 | 0 | 3 | 7 | 10 | 30.0% |
4 | 180 | V180 | 2 | 0 | 0 | 4 | 6 | 10 | 40.0% |
5 | 360 | V360 | 1 | 1 | 0 | 4 | 5 | 10 | 50.0% |
6 | 360 | V360 | 2 | 0 | 0 | 2 | 8 | 10 | 20.0% |
7 | 540 | V540 | 1 | 1 | 0 | 2 | 7 | 10 | 30.0% |
8 | 540 | V540 | 2 | 0 | 0 | 4 | 6 | 10 | 40.0% |
Obs | Participant ID | Site ID | Completed Visits | On-Time Visits | Early Visits | Late Visits | Missed Visits | Completion Rate (%) | Most Recent Visit Date |
---|---|---|---|---|---|---|---|---|---|
1 | P001 | 1 | 4 | 0 | 0 | 4 | 0 | 100.0% | 23MAR2026 |
2 | P002 | 1 | 2 | 1 | 0 | 1 | 2 | 50.0% | 06APR2026 |
3 | P003 | 1 | 1 | 0 | 0 | 1 | 3 | 25.0% | 01OCT2024 |
4 | P004 | 1 | 2 | 0 | 0 | 2 | 2 | 50.0% | 07SEP2025 |
5 | P005 | 1 | 2 | 0 | 0 | 2 | 2 | 50.0% | 29MAR2025 |
6 | P006 | 1 | 0 | 0 | 0 | 0 | 4 | 0.0% | . |
7 | P007 | 1 | 4 | 1 | 0 | 3 | 0 | 100.0% | 02MAR2026 |
8 | P008 | 1 | 0 | 0 | 0 | 0 | 4 | 0.0% | . |
9 | P009 | 1 | 0 | 0 | 0 | 0 | 4 | 0.0% | . |
10 | P010 | 1 | 2 | 1 | 0 | 1 | 2 | 50.0% | 29SEP2025 |
Obs | Participant ID | Site ID | Target Date | Scheduled Visit | Window Start | Window End | Visit Pending/Expired Status |
---|---|---|---|---|---|---|---|
1 | P001 | 1 | 23SEP2024 | V0 | 23SEP2024 | 22DEC2024 | EXPIRED |
2 | P002 | 1 | 13OCT2024 | V0 | 13OCT2024 | 11JAN2025 | EXPIRED |
3 | P003 | 1 | 26SEP2024 | V0 | 26SEP2024 | 25DEC2024 | EXPIRED |
4 | P004 | 1 | 08SEP2024 | V0 | 08SEP2024 | 07DEC2024 | EXPIRED |
5 | P005 | 1 | 22SEP2024 | V0 | 22SEP2024 | 21DEC2024 | EXPIRED |
6 | P006 | 1 | 01SEP2024 | V0 | 01SEP2024 | 30NOV2024 | EXPIRED |
7 | P007 | 1 | 05SEP2024 | V0 | 05SEP2024 | 04DEC2024 | EXPIRED |
8 | P008 | 1 | 20SEP2024 | V0 | 20SEP2024 | 19DEC2024 | EXPIRED |
9 | P009 | 1 | 07OCT2024 | V0 | 07OCT2024 | 05JAN2025 | EXPIRED |
10 | P010 | 1 | 04OCT2024 | V0 | 04OCT2024 | 02JAN2025 | EXPIRED |
This design front-loads follow-up soon after baseline.
Visits are scheduled on Day 7, Day 14, Day 28, then monthly at 2 and 3 months.
Windows are narrow (±3 to 7 days), so protocol deviations appear quickly if visits slip.
Obs | Scheduled Visit | Site ID | On-Time | Early | Late | Missed | Total Expected | Completion Rate (%) |
---|---|---|---|---|---|---|---|---|
1 | V0 | 1 | 0 | 2 | 4 | 2 | 8 | 75.0% |
2 | V0 | 2 | 1 | 4 | 4 | 3 | 12 | 75.0% |
3 | V0 | 3 | 0 | 2 | 6 | 2 | 10 | 80.0% |
4 | V7 | 1 | 1 | 2 | 5 | 0 | 8 | 100.0% |
5 | V7 | 2 | 1 | 3 | 4 | 4 | 12 | 66.7% |
6 | V7 | 3 | 1 | 3 | 5 | 1 | 10 | 90.0% |
7 | V14 | 1 | 1 | 4 | 0 | 3 | 8 | 62.5% |
8 | V14 | 2 | 1 | 1 | 6 | 4 | 12 | 66.7% |
9 | V14 | 3 | 1 | 6 | 2 | 1 | 10 | 90.0% |
10 | V28 | 1 | 1 | 2 | 4 | 1 | 8 | 87.5% |
Here, each participant has their own target schedule, stored in a lookup table.
Visit names (e.g., D3, D10, W4, M2) are not tied to simple day offsets, so the macro uses a mapping to preserve the intended order.
This reflects studies where calendars differ per subject (e.g., post-surgery, post-delivery, or custom event-based follow-up).
Obs | Participant ID | Site ID | Scheduled Visit | Target Date | Visit Window Start | Visit Window End | Actual Visit Date | Difference (Actual - Target, Days) | Visit Status (On-Time/Early/Late/Missed) |
---|---|---|---|---|---|---|---|---|---|
1 | E3_001 | 1 | D3 | 04MAR2025 | 02MAR2025 | 09MAR2025 | . | . | MISSED |
2 | E3_001 | 1 | D10 | 11MAR2025 | 09MAR2025 | 16MAR2025 | 11MAR2025 | 0 | ON_TIME |
3 | E3_001 | 1 | W4 | 29MAR2025 | 27MAR2025 | 03APR2025 | 02APR2025 | 4 | LATE |
4 | E3_001 | 1 | M2 | 29APR2025 | 27APR2025 | 04MAY2025 | 30APR2025 | 1 | LATE |
5 | E3_002 | 1 | D3 | 19FEB2025 | 17FEB2025 | 24FEB2025 | 17FEB2025 | -2 | EARLY |
6 | E3_002 | 1 | D10 | 26FEB2025 | 24FEB2025 | 03MAR2025 | . | . | MISSED |
7 | E3_002 | 1 | W4 | 16MAR2025 | 14MAR2025 | 21MAR2025 | . | . | MISSED |
8 | E3_002 | 1 | M2 | 16APR2025 | 14APR2025 | 21APR2025 | 16APR2025 | 0 | ON_TIME |
9 | E3_003 | 2 | D3 | 20MAR2025 | 18MAR2025 | 25MAR2025 | 20MAR2025 | 0 | ON_TIME |
10 | E3_003 | 2 | D10 | 27MAR2025 | 25MAR2025 | 01APR2025 | 25MAR2025 | -2 | EARLY |
The LAG policy allows the post-window to extend longer than the pre-window.
In this case, quarterly visits (Q1–Q4) have a nominal ±7/21-day window, but the LAG logic expands the post-allowance further based on interval length.
This mimics operational rules where late arrivals are tolerated, but very early visits are not.
Obs | Scheduled Visit | Site ID | On-Time | Early | Late | Missed | Total Expected | Completion Rate (%) |
---|---|---|---|---|---|---|---|---|
1 | V0 | 1 | 1 | 4 | 8 | 7 | 20 | 65.0% |
2 | V0 | 2 | 1 | 3 | 4 | 12 | 20 | 40.0% |
3 | V90 | 1 | 0 | 4 | 5 | 11 | 20 | 45.0% |
4 | V90 | 2 | 3 | 3 | 5 | 9 | 20 | 55.0% |
5 | V180 | 1 | 1 | 2 | 10 | 7 | 20 | 65.0% |
6 | V180 | 2 | 3 | 3 | 8 | 6 | 20 | 70.0% |
7 | V270 | 1 | 0 | 5 | 10 | 5 | 20 | 75.0% |
8 | V270 | 2 | 0 | 4 | 9 | 7 | 20 | 65.0% |
9 | V360 | 1 | 0 | 5 | 7 | 8 | 20 | 60.0% |
10 | V360 | 2 | 0 | 3 | 10 | 7 | 20 | 65.0% |
style='text-align:center; font-size:16px; line-height:1.4;'>Weekly visits (baseline through Week 8) are scheduled tightly with only a ±2–3 day tolerance.
style='text-align:center; font-size:16px; line-height:1.4;'>Because windows are narrow and cadence is high, the model naturally produces more out-of-window flags.
style='text-align:center; font-size:16px; line-height:1.4;'>This design mirrors intensive follow-up protocols such as early treatment monitoring.
Obs | Participant ID | Site ID | Completed Visits | On-Time Visits | Early Visits | Late Visits | Missed Visits | Completion Rate (%) | Most Recent Visit Date |
---|---|---|---|---|---|---|---|---|---|
1 | E5_001 | 2 | 5 | 2 | 2 | 1 | 4 | 55.6% | 03JUN2025 |
2 | E5_002 | 1 | 7 | 1 | 1 | 5 | 2 | 77.8% | 15JUN2025 |
3 | E5_003 | 1 | 6 | 4 | 2 | 0 | 3 | 66.7% | 12JUN2025 |
4 | E5_004 | 4 | 6 | 2 | 4 | 0 | 3 | 66.7% | 25MAY2025 |
5 | E5_005 | 4 | 8 | 4 | 1 | 3 | 1 | 88.9% | 08JUN2025 |
6 | E5_006 | 4 | 5 | 2 | 1 | 2 | 4 | 55.6% | 02JUN2025 |
7 | E5_007 | 1 | 4 | 2 | 0 | 2 | 5 | 44.4% | 20MAY2025 |
8 | E5_008 | 1 | 6 | 3 | 1 | 2 | 3 | 66.7% | 26MAY2025 |
9 | E5_009 | 3 | 8 | 6 | 1 | 1 | 1 | 88.9% | 10JUN2025 |
10 | E5_010 | 2 | 8 | 5 | 1 | 2 | 1 | 88.9% | 11JUN2025 |
Across these examples, visit_tracker
generated expected schedules, applied windows, greedily matched actuals to targets, and summarized on-time/early/late/missed outcomes at both participant and visit levels. The plots visualize completion/retention with an optional target line.
Choose an INTERVAL schedule for simple baseline-offset calendars or a LOOKUP schedule for per-ID targets and custom visit naming. Use order_map_ds=
or lookup_order_var=
to control non-chronological display order.
window_def
, window_pre
, window_post
to match protocol tolerance.order_map_ds=
for labels like BL, D3, W4, M2.target_rate=
(e.g., 0.80
for 80).out_*
tables to integrate with your reporting pipeline.Report generated on August 29, 2025.