Skip to contents

Scores every multi-record person cluster produced by link_panel() on how consistent its member records are from year to year, and sorts each flagged cluster into one primary explanation. The intent is triage: separate the small set of genuinely questionable links (same surname, materially different given name, or a near-miss surname that may be two different people) from the large set whose apparent disagreement has a benign, mechanical cause (a nickname, a maiden/compound surname, a field-order swap, or an upstream parser artifact).

Usage

flag_links(
  df,
  emp_id = "EMP_ID",
  org_id = "ein",
  org_name = "org.name",
  year = "taxyr",
  raw_name = "name.raw",
  first = "first_name",
  last = "last_name",
  divergence_lv = 0.15,
  divergence_jw = 0.15,
  last_sim_floor = 0.85,
  first_sim_floor = 0.85,
  hon = honorific_tokens(),
  cred = credential_tokens()
)

Arguments

df

A linked panel: the output of link_panel() (or any frame carrying the person id, org, year, raw name, and parsed given/surname columns).

emp_id, org_id, org_name, year

Column names for the cross-year person id, organization id, organization name, and tax year.

raw_name, first, last

Column names for the raw (pre-parse) name string and the parsed given and surname components.

divergence_lv, divergence_jw

Raw-name divergence thresholds above which a cluster is flagged (normalised Levenshtein and Jaro-Winkler distance).

last_sim_floor, first_sim_floor

Similarity floors (via compare_last_names/compare_first_names) at or above which surnames or given names are treated as agreeing when assigning a category.

hon, cred

Token sets for honorific-glue and credential detection; see honorific_tokens() and credential_tokens().

Value

A data frame with one row per multi-record person, class "synthid_link_flags", ordered with the review queue first. Key columns: category, review_flag, review_score, the per-criterion flags (flag_first_disagree, flag_last_disagree, flag_name_divergence), the agreement metrics (last_sim, first_sim, name_lv_norm, name_jw), and the distinct values seen (names_seen, first_seen, last_seen). A summary (thresholds, person and flag counts, category tally) is attached as the "synthid_flags" attribute.

Details

A cluster is flagged when any of three criteria trip: the parsed first names disagree, the parsed last names disagree, or the raw name strings diverge beyond divergence_lv (normalised Levenshtein) or divergence_jw (Jaro-Winkler). Every flagged cluster is then assigned, in priority order, to the first matching category:

order_swap

two raw names share the same tokens in different order (e.g. "SMITH BRAD" vs "BRAD SMITH") – a correct link.

parser_honorific_glue

a honorific is fused onto the given name ("MRWILLIAM") or a single letter onto the surname ("WSMITH") – a correct link exposing an upstream parser defect (see parse_fail_log()).

surname_credential

post-nominal credentials leaked into the surname ("MCNEIL" vs "RM RDMS RVT CRA MCNEIL") – also a parser defect.

surname_compound

the surnames reconcile as a maiden/hyphenated or reordered compound (compare_last_names \(\ge\) last_sim_floor).

nickname_or_spelling

surnames agree and the given names agree as a nickname, initial, or minor spelling variant (compare_first_names \(\ge\) first_sim_floor) – a correct link.

review

residual: nothing benign explains the divergence. This is the human queue; see link_review_queue().

See also

link_review_queue() for the residual queue, parse_fail_log() for the parser-defect handoff.

Examples

if (FALSE) { # \dontrun{
linked <- link_panel(panel)
flags  <- flag_links(linked)
table(flags$category)
review <- link_review_queue(flags)
} # }