Analyze appointment no-shows without making clinical claims
In this article (6 sections)
A no-show is an administrative outcome under a defined appointment policy. It should not be inferred merely because a service-end timestamp is missing. Cancellations, future appointments and unresolved records need separate treatment before calculating the rate.
The analysis can identify recording gaps and operational patterns. It does not establish a person's motivation, clinical need or the causal effect of a reminder.
Define the population and cutoff
Use the entirely fictional appointment fixture. Evaluate appointments scheduled on January 10, 2026, using a cutoff of January 11 at midnight in the fixture's fixed local timezone.
There are six scheduled records: three completed, one confirmed no-show, one advance cancellation and one unknown outcome. Exclude the advance cancellation from this exercise's eligible no-show population. The January 11 appointment is still future and is excluded as well.
This leaves five eligible appointments. Four have resolved outcomes and one remains unknown.
Count outcome categories before dividing
SELECT status,COUNT(*) AS appointments
FROM appointments
WHERE scheduled_at>='2026-01-10T00:00:00'
AND scheduled_at<'2026-01-11T00:00:00'
GROUP BY status ORDER BY status;The confirmed no-show rate among resolved eligible records is 1/4 = 25%. The known no-shows as a share of all eligible appointments are 1/5 = 20%, but that is a lower bound while one outcome is unknown.
from build_and_verify import database
db = database()
rows = db.execute("""SELECT * FROM appointments
WHERE scheduled_at>='2026-01-10T00:00:00'
AND scheduled_at<'2026-01-11T00:00:00'""").fetchall()
db.close()
eligible = [r for r in rows if r[5]!='cancelled_advance']
resolved = [r for r in eligible if r[5] in ('completed','no_show')]
missing = [r for r in eligible if r[5]=='unknown']
no_shows = sum(r[5]=='no_show' for r in eligible)
assert (len(rows),len(eligible),len(resolved),len(missing),no_shows)==(6,5,4,1,1)
lower = no_shows/len(eligible)
upper = (no_shows+len(missing))/len(eligible)
assert lower==.2 and upper==.4
assert no_shows/len(resolved)==.25
print({'resolved_record_rate':.25,'all_eligible_lower':lower,
'all_eligible_upper':upper,'outcome_coverage':len(resolved)/len(eligible)})The all-eligible rate lies between 20% and 40% if the unknown outcome could resolve as either attendance or no-show under this simplified contract. This is a missing-outcome bound, not a sampling confidence interval.
Match cancellation definitions to the source
NHS England's DNA improvement guidance specifies exclusions for its reporting context. Those definitions should not be assumed to govern every healthcare system or appointment dataset.
Record cancellation time and initiator when they matter to the operational question. A cancellation that frees a slot days ahead differs from one recorded after the scheduled time, and a provider cancellation differs from a patient cancellation. The compact fixture only supplies the advance-cancellation category and cannot analyze those distinctions further.
Do not turn reminder association into an effect estimate
The dataset includes a reminder indicator. Comparing reminded and unreminded appointments would still not establish that reminders caused any difference: assignment was not randomized, the groups are tiny and relevant differences are unobserved.
People may receive reminders based on channel availability, booking process or other operational rules. Those factors can also relate to attendance. A causal evaluation needs a suitable design, a defined intervention and appropriate outcome measurement.
Avoid labeling individuals as unreliable from a no-show record. Administrative errors, transport, communication and changing circumstances are not measured here. The useful immediate action is to verify records and investigate service processes, not infer personal characteristics.
Report the next operational step
For this fixture, the first task is to reconcile A6's unknown outcome. Its arrival timestamp already shows why “missing completion equals no-show” would be an unsafe rule. After data quality is established, a larger analysis can examine compatible appointment groups and test a concrete service improvement.
Exercise: change A6 to completed after a delayed update. Recalculate both the resolved-record rate and the full eligible rate, then explain why the original report should have marked its result provisional.
NeuraPath's Data Analytics with Generative AI course connects categorical data quality with operational reporting. A useful no-show analysis makes eligibility, missing outcomes and the limits of interpretation explicit.
Continue learning
This article is part of the Domain analytics and business cases sequence. Use the neighbouring tasks when you need the prerequisite or the next application.
- Review the prerequisite or neighbouring task in Healthcare operations analytics using synthetic appointment data.
- Continue with Education cohort analytics: attendance, completion and missing records.
Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.
This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.
Explore Data Analytics with Generative AI