If your baseline roster contains one row per student, join the follow-up scores to that roster before comparing groups. A table made from follow-up submissions alone hides the students who did not return.
This Python example uses synthetic records. None means a missing score. A score of zero is a recorded score.
from collections import Counter roster = {"a1": "A", "a2": "A", "a3": "A", "b1": "B", "b2": "B"} follow_up = {"a1": 12, "a2": 0, "b1": 15} enrolled = Counter(roster.values()) observed = Counter( group for student, group in roster.items() if follow_up.get(student) is not None ) for group, total in sorted(enrolled.items()): missing = total - observed[group] print(f"{group}: {missing}/{total} missing ({missing / total:.1%})") The example prints A: 1/3 missing (33.3%) and B: 1/2 missing (50.0%). Keep the counts next to the percentages. Before applying this to a real study, check for duplicate IDs and follow-up IDs absent from the baseline roster. These counts show who is missing and help frame a sensitivity analysis. They cannot reveal the missing scores.
I work on RigorMed, an AI research workspace. A useful handoff for this step includes the baseline roster, the join key and the missingness table.