Skip to contents

Panel linkage

The end-to-end entry point: assign a stable cross-year EMP_ID to every record in a compensation panel, and report on the run.

link_panel()
Assign stable cross-year person identifiers to a compensation panel
synthid_report()
Print a summary of a linkage run
synthid_cols()
Standard column names for a titleclassifier/peopleparser panel

Synthetic identifiers

Deterministic, reproducible identifiers. PERSON_YEAR_ID links a record back to its source Part VII row; EMP_ID identifies a person across years.

person_year_id()
Build deterministic per-record person-year identifiers from source keys
create_emp_ids()
Hash a vector of strings into deterministic EMP identifiers
build_id_string()
Build a canonical, human-readable per-record identifier string

Match scoring and model

The Fellegi-Sunter machinery: per-field comparison vectors, the additive hand-weighted score, and the unsupervised EM latent-class model.

candidate_comparisons()
All candidate pairs with their per-field comparison vectors
candidate_scores()
Score all candidate cross-year pairs (for evaluation and threshold tuning)
default_weights()
Default component weights for the person-match score
fit_match_model()
Fit a match model to candidate comparison vectors
predict_match()
Predict a calibrated match probability for comparison vectors
fs_weights()
Learned Fellegi-Sunter agreement / disagreement weights (EM models)

Name comparison

The comparators that make linkage robust: a compound surname comparator, a nickname/phonetic-aware first-name comparator, and surname-rarity weighting.

compare_two_names()
Similarity between two (possibly compound) surnames
compare_first_names()
Compare two first names, with nickname, initial, and phonetic handling
compare_last_names()
Vectorised compound-name comparator
preprocess_name()
Split a (possibly compound) name into comparable tokens
nickname_table()
Nickname / diminutive dictionary
surname_weight()
Within-organization surname-rarity weight, per record
population_surname_weight()
Population surname-rarity weight

Cross-organization linkage

Link the same person across different organizations (interlocking directorates) via person profiles and hash-lookup blocking.

link_cross_org()
Cross-organization person linkage (interlock) pipeline
build_person_profile()
Reduce an EMP_ID cluster to a canonical person profile
blocking_passes()
Blocking passes for cross-organization candidate generation
person_blocking_keys()
Explode person profiles into a long blocking-key table
candidate_pairs()
Generate cross-organization candidate pairs by hash join
score_candidate_pairs()
Score cross-organization candidate pairs from their profiles
filter_edges_by_role()
Filter cross-organization edges by the role composition of their endpoints
board_only_edges()
Board-governance interlock edges
non_board_edges()
Non-board (paid-employee) edges
stamp_xorg()
Stamp cross-org person ids back onto the record-level panel

Title roles

A coarse role taxonomy (BOARD / OFFICER / STAFF / OTHER) over standardized titles, used to reason about the composition of a match.

title_role
Coarse role taxonomy over standardized titles
classify_title_role()
Assign a coarse role to standardized titles
title_role_rules()
Regex rules behind classify_title_role()
title_role_coverage()
Audit the role assignment for a title vocabulary

Post-linkage quality control: flag links for human review and surface upstream name-parser defects for handoff.

flag_links()
Flag questionable cross-year person links for review
link_review_queue()
The residual human-review queue
parse_fail_log()
Record-level parser-defect log for peopleparser
parse_fail_tokens()
Roll a parse-fail log up into candidate title/credential tokens
honorific_tokens() credential_tokens()
Token sets used by the link-review flaggers