A researcher asks for an extract. Someone drops name, address, and patient number, and sends it. The data feels anonymous. It usually is not.
Quasi-identifiers do the work
The classic result is that a small combination of ordinary fields — date of birth, sex, and a granular postcode — uniquely identifies a large share of a population. None of those is a direct identifier. All of them are usually left in.
Add a rare diagnosis, an admission date, or a hospital site and uniqueness gets worse rather than better.
Generalise before you remove
The useful move is reducing precision rather than deleting columns:
- Date of birth becomes year, or an age band. Age 90+ collapses into one bucket.
- Postcode drops to district.
- Rare diagnoses roll up to a parent category.
- Exact timestamps become the week.
The extract stays analytically useful and stops being a lookup table.
Check the smallest group
Before releasing, count how many people share each combination of the remaining quasi-identifiers. If any group has one member, that row is identifiable regardless of what you removed.
SELECT ...quasi-identifiers..., count(*)
GROUP BY ...
HAVING count(*) < 5
Rows in groups below your threshold get suppressed or generalised further. That threshold is a policy decision someone must sign, and it should be written down next to the extract definition rather than in someone’s memory.
Pseudonymisation is not anonymisation
Replacing the patient number with a stable hash still lets anyone with the same hash function re-identify by trying candidates. It is a useful control for linking datasets internally; it does not make the extract safe to publish. Treat pseudonymised data as identifiable data with an extra step, and govern it that way.
Make the extract reproducible
Store the extract definition — filters, generalisation rules, suppression threshold, date — as a record, not a one-off script on a laptop. When someone asks what was released to whom in March, that is the only thing that answers it, and it is also what lets you re-run the same extract without re-deriving the rules from scratch.