Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog_entry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- bump: minor
changes:
added:
- highest_education variable derived from FRS EDUCQUAL field.
44 changes: 44 additions & 0 deletions policyengine_uk_data/datasets/frs.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,50 @@ def determine_education_level(fted_val, typeed2_val, age_val):
index=pe_person.index,
)

# Add highest education from EDUCQUAL (highest qualification achieved)
# Codes from FRS ADT_324X classification; unmapped codes default to UPPER_SECONDARY
EDUCQUAL_MAP = {
1: "NOT_COMPLETED_PRIMARY",
2: "LOWER_SECONDARY", # GCSE D-G / CSE 2-5
3: "LOWER_SECONDARY", # GCSE A-C / O-level A-C
4: "UPPER_SECONDARY", # AS-level
5: "UPPER_SECONDARY", # A-level (1 subject)
6: "UPPER_SECONDARY", # A-level (2 subjects)
7: "UPPER_SECONDARY", # A-level (3+ subjects)
8: "LOWER_SECONDARY", # Scottish Standard/Ordinary Grade
9: "UPPER_SECONDARY", # Scottish Higher Grade
10: "UPPER_SECONDARY", # Scottish 6th Year Studies
11: "POST_SECONDARY", # HNC/HND
12: "POST_SECONDARY", # City & Guilds advanced / BTEC National
13: "UPPER_SECONDARY", # City & Guilds craft / BTEC General
14: "POST_SECONDARY", # ONC/OND / BTEC National (lower)
15: "UPPER_SECONDARY", # City & Guilds foundation
16: "POST_SECONDARY", # RSA advanced
17: "TERTIARY", # First/foundation degree
18: "TERTIARY", # Second degree
19: "TERTIARY", # Higher degree (Masters/PhD)
20: "TERTIARY", # PGCE / teaching qualification
21: "TERTIARY", # Nursing/paramedical qualification
66: "UPPER_SECONDARY", # NVQ/SVQ Level 1
67: "UPPER_SECONDARY", # NVQ/SVQ Level 2
68: "UPPER_SECONDARY", # NVQ/SVQ Level 3
69: "POST_SECONDARY", # NVQ/SVQ Level 4
70: "TERTIARY", # NVQ/SVQ Level 5
}
# Codes 22-65 and 71-85 are further vocational/professional qualifications;
# treat as POST_SECONDARY. Codes 86-87 are catch-alls; treat as UPPER_SECONDARY.
for code in range(22, 66):
EDUCQUAL_MAP[code] = "POST_SECONDARY"
for code in range(71, 86):
EDUCQUAL_MAP[code] = "POST_SECONDARY"
EDUCQUAL_MAP[86] = "UPPER_SECONDARY"
EDUCQUAL_MAP[87] = "UPPER_SECONDARY"

educqual = pd.to_numeric(person.educqual, errors="coerce")
pe_person["highest_education"] = educqual.map(EDUCQUAL_MAP).fillna(
"UPPER_SECONDARY"
)

# Add employment status
EMPLOYMENTS = [
"CHILD",
Expand Down
9 changes: 9 additions & 0 deletions policyengine_uk_data/tests/test_highest_education.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from policyengine_uk import Microsimulation


def test_highest_education(frs):
sim = Microsimulation(dataset=frs)
values = sim.calculate("highest_education", period=2025)
assert "TERTIARY" in set(values)
assert "LOWER_SECONDARY" in set(values)
assert "UPPER_SECONDARY" in set(values)