Title roles: BOARD / OFFICER / STAFF / OTHER
title-roles.RmdThe title.standard vocabulary from titleclassifier has ~250 values — too fine to reason about the composition of a match. classify_title_role() collapses it into four coarse roles used by cross-organization linkage and interlock studies.
The four roles
classify_title_role(c(
"BOARD PRESIDENT", "BOARD SECRETARY", "TREASURER", # governance -> BOARD
"CHIEF FINANCIAL OFFICER", "EXECUTIVE DIRECTOR", # management -> OFFICER
"VICE PRESIDENT", # governance -> BOARD
"VICE PRESIDENT OF FINANCE", # functional -> STAFF
"DIRECTOR OF MARKETING", # functional -> STAFF
"CHAPLAIN" # unmatched -> OTHER
))
#> [1] BOARD BOARD BOARD OFFICER OFFICER BOARD STAFF STAFF OTHER
#> Levels: BOARD OFFICER STAFF OTHER-
BOARD— the governance body and its elected officers. Per the interlock use case, the governance triad (president / treasurer / secretary) isBOARD, notOFFICER. -
OFFICER— paid executive leadership: the C-suite, executive director, general manager, general counsel, comptroller. -
STAFF— other paid employees: functional directors and vice presidents, managers, coordinators, clerks. -
OTHER— anything unmatched (e.g.CHAPLAIN,HISTORIAN), by design, so the classifier stays safe on the long tail.
The distinction that does the work
A governance title carrying a functional qualifier is a paid post, not a governance seat. Any title containing " OF " is excluded from BOARD:
classify_title_role(c("VICE PRESIDENT", "VICE PRESIDENT OF FINANCE"))
#> [1] BOARD STAFF
#> Levels: BOARD OFFICER STAFF OTHERBy default the result is an ordered factor (levels = TRUE) so roles sort BOARD < OFFICER < STAFF < OTHER; pass levels = FALSE for a plain character vector.
Inspecting the rules
The rule set is exported and inspectable — the classifier is not a black box:
str(title_role_rules(), max.level = 1)
#> List of 3
#> $ board : chr "^((VICE|CO|FIRST|SECOND|THIRD|FOURTH|1ST|2ND|3RD|4TH|SR|JR|SENIOR|JUNIOR|ASSISTANT|ASST|ASSOCIATE|ASSOC|DEPUTY|"| __truncated__
#> $ officer: chr "^C[A-Z]?[EFOAITDMR]O$|CHIEF .*OFFICER|EXECUTIVE DIRECTOR|EXECUTIVE VICE PRESIDENT|GENERAL MANAGER|MANAGING DIRE"| __truncated__
#> $ staff : chr " OF |DIRECTOR$|DIRECTOR |MANAGER|COORDINATOR|ADMINISTRATOR|SUPERVISOR|CLERK|EMPLOYEE|^STAFF$|ASSISTANT|WEBMASTE"| __truncated__Auditing coverage and pinning exceptions
Because unmatched titles fall to OTHER on purpose, you should audit what lands there for your corpus. title_role_coverage() returns one row per distinct title with its frequency and assigned role:
titles <- c(rep("BOARD PRESIDENT", 5), rep("EXECUTIVE DIRECTOR", 3),
rep("DIRECTOR OF NURSING", 2), "SERGEANT AT ARMS", "CHAPLAIN")
cov <- title_role_coverage(titles)
cov
#> title n role
#> 1 BOARD PRESIDENT 5 BOARD
#> 2 EXECUTIVE DIRECTOR 3 OFFICER
#> 3 DIRECTOR OF NURSING 2 STAFF
#> 4 CHAPLAIN 1 OTHER
#> 5 SERGEANT AT ARMS 1 OTHER
# The tail worth reviewing:
subset(cov, role == "OTHER")
#> title n role
#> 4 CHAPLAIN 1 OTHER
#> 5 SERGEANT AT ARMS 1 OTHERWhen you find a title in OTHER that belongs elsewhere, pin it with overrides instead of editing rules — the override wins:
classify_title_role(c("SERGEANT AT ARMS", "CHAPLAIN"),
overrides = c("SERGEANT AT ARMS" = "BOARD"))
#> [1] BOARD OTHER
#> Levels: BOARD OFFICER STAFF OTHERWhere roles are used
Role assignment drives the edge filters in cross-organization linkage — board_only_edges() keeps board-to-board interlocks, non_board_edges() the rest. See Cross-organization linkage.
See also
-
classify_title_role(),title_role_rules(),title_role_coverage()in the reference. ```