Reduce an EMP_ID cluster to a canonical person profile
build_person_profile.RdCollapses every record of a within-organization person (all rows sharing an
EMP_ID, as stamped by link_panel()) into one structured profile row for
cross-organization linkage. Deliberately does not flatten the cluster to a
single canonical name string: the variant sets are what carry a person from
one organization's filing to another's (a maiden/married surname, an OCR
variant, a nickname), so each name field keeps both a deterministic canonical
value (for display and as a primary blocking key) and the full set of observed
variants (for blocking recall and pairwise scoring).
Usage
build_person_profile(
df,
cols = synthid_cols(),
emp_id = "EMP_ID",
title = "title.standard",
state = NULL,
ntee = NULL,
overrides = NULL
)Arguments
- df
A linked panel: the output of
link_panel()(or any frame carryingEMP_IDplus parsed name components). Multiple rows perEMP_ID.- cols
Column mapping; see
synthid_cols(). Usesorg_id,year,name, and the name-component features (first_name,middle_name,last_name,suffix,gender).- emp_id
Name of the person-cluster id column (default
"EMP_ID").- title
Name of the standardized-title column, classified into a coarse role via
classify_title_role()(default"title.standard"; skipped if absent).- state, ntee
Optional column names for organization geography and NTEE industry. When present they are carried into the profile as variant sets and are available as relaxable blocking dimensions; when
NULLor absent they are skipped (join them from the BMF beforehand if you want them).- overrides
Passed to
classify_title_role()for title tail cases.
Value
A data frame, one row per EMP_ID, with scalar summary columns and
list-columns for the variant sets:
EMP_ID,n_records,n_orgs,n_years,first_year,last_yearCluster size and span.
last_name,last_name_variants,last_name_keysModal surname; the distinct surnames observed; their phonetic (Soundex) blocking keys.
first_name,first_name_variants,first_name_roots,first_initialMost-complete formal given name; distinct given names; their canonical nickname roots (
first_name_roots()); leading initial.middle_initials,suffixes,genderUnion of middle initials and suffixes; modal gender (
NAon tie/unknown).name_variantsDistinct full-name strings seen for the person.
primary_role,roles,is_boardModal coarse role; the role set; whether the person ever held a
BOARDseat.titles,orgs,yearsDistinct standardized titles, organization ids, and tax years for the person.
states,nteePresent only when
state/nteeare supplied.
List-columns hold one character vector per person; unnest last_name_keys
(with EMP_ID) to get the long key table for the stage-1 hash join.
Details
The profile is the unit compared in the cross-org stage. Stage 1 (candidate
generation) is a hash/inverted-index lookup on blocking keys rather than a
materialized within-block cross product: a profile emits one key per surname
variant (last_name_keys, phonetic), lands in every matching bucket, and only
profiles sharing a bucket are scored – so maiden/married/OCR variants are not
silently dropped, and a common surname never materializes an all-pairs block.
Examples
if (FALSE) { # \dontrun{
linked <- link_panel(panel)
profiles <- build_person_profile(linked)
# long blocking-key table for the cross-org hash join:
keys <- do.call(rbind, Map(function(id, k) data.frame(EMP_ID = id, key = k),
profiles$EMP_ID, profiles$last_name_keys))
} # }