Skip to contents

governance and panel990

The governance package scores nonprofit governance; it does not retrieve data. Retrieving, normalizing, and assembling IRS 990 efile tables is the job of the companion panel990 package.

Package Role
panel990 Download efile tables, filter to a sample frame, merge to one row per filing, build panels.
governance Normalize the governance fields into a feature matrix (get_features()) and compute the governance index (get_scores()).

governance calls panel990 for you through get_governance_data() and get_governance_scores(), so most users never touch panel990 directly. This vignette shows both the one-call path and the underlying panel990 workflow for when you want more control. Install panel990 first:

remotes::install_github("Nonprofit-Open-Data-Collective/panel990")

Required 990 tables

The governance index is built from four efile tables — Form 990 Parts IV, VI, and XII and Schedule M. Each is a panel990 table name you pass to panelize() (Part XII also has the short alias "P12").

Part / Schedule Governance information it contains panel990 table name
Part IV Required-schedule triggers: audited financials, interested-person business transactions, large non-cash and art/historical contributions F9-P04-T00-REQUIRED-SCHEDULES
Part VI Governing body composition (voting / independent members) and governance & management policies (conflict-of-interest, whistleblower, document retention, CEO compensation process, document availability) F9-P06-T00-GOVERNANCE
Part XII Financial-reporting method (cash / accrual / other) and audit oversight F9-P12-T00-FINANCIAL-REPORTING
Schedule M Review process for unusual non-cash gifts SM-P01-T00-NONCASH-CONTRIBUTIONS

Full 990 filers only. The governance index does not apply to 990EZ returns — they omit these Parts. Restrict the data to RETURN_TYPE == "990" (shown below). get_governance_data() does this for you.

get_governance_data() builds the full-990 sample frame, downloads the four tables, keeps the needed columns, and merges them to one row per filing — ready for get_features().

library(governance)

# Assemble the raw fields for a tax year (full 990 filers only)
dat <- get_governance_data(years = 2022)

features <- get_features(dat)
scores   <- get_scores(features)

# ...or the whole pipeline in one call
scores <- get_governance_scores(years = 2022)

Restrict to specific organizations with eins (formatted EIN2 values), or read tables you have already downloaded by pointing the source at a directory:

scores <- get_governance_scores(years = 2022, eins = c("EIN-43-2031361"))

src <- panel990::data_source(root = "path/to/efile/csvs")
dat <- get_governance_data(years = 2022, source = src)

Option 2: the panel990 workflow

Under the hood, get_governance_data() assembles a sample frame and calls panel990::panelize(). Doing it yourself gives full control — additional filters, multiple years, BMF traits, DuckDB backends, and so on.

The form_type filter is how you keep only full 990 filers: it is a built-in sample-frame alias mapping to the RETURN_TYPE column, so form_type = "990" keeps only RETURN_TYPE == "990".

library(panel990)

gov_tables <- c(
  "F9-P04-T00-REQUIRED-SCHEDULES",
  "F9-P06-T00-GOVERNANCE",
  "F9-P12-T00-FINANCIAL-REPORTING",
  "SM-P01-T00-NONCASH-CONTRIBUTIONS"
)

# Sample frame: keep full 990 filers (RETURN_TYPE == "990") via the SFW filter
sfw <- create_sfw("governance panel", form_type = "990")

# Download, filter, and merge the tables into one row per filing
panel <- panelize(sfw = sfw, tables = gov_tables, years = 2022)

dat <- as.data.frame(panel)
scores <- get_scores(get_features(dat))

create_sfw() accepts other convenience filters too — for example state = "CA" or years = 2018:2022 — which panelize() pushes down to the download step. See ?panel990::create_sfw and ?panel990::panelize.

A note on normalization

get_features() performs the governance-specific normalization itself (blank checkboxes and counts become 0 regardless of how the source encoded them), so the tables are imported raw.

panel990::panel_normalize() only rewrites blank financial fields (revenue, expenses, balance sheet) to zero; it leaves the governance checkbox and count fields untouched. It is therefore safe to include in a shared pipeline but is neither required nor sufficient for the governance features — get_features() is what normalizes them. (Do not run the general panel990::normalize() on the governance checkboxes before get_features(): it converts them to logicals, which get_features() does not expect.)

The input contract

However you obtain the data, get_features() expects a data frame with one row per filing containing ORG_EIN plus the raw fields below. Values may be encoded as "true"/"false", "1"/"0", "X" flags, or blanks (NA or ""); get_features() normalizes all of these.

Part/Schedule Variable 990 line Question
Part IV F9_04_AFS_IND_X 12a Independent audited financial statements?
Part IV F9_04_BIZ_TRANSAC_DTK_X 28a Business transaction with a current/former officer, director, trustee, or key employee (DTK)?
Part IV F9_04_BIZ_TRANSAC_DTK_FAM_X 28b …with a family member of a DTK?
Part IV F9_04_BIZ_TRANSAC_DTK_ENTITY_X 28c …with a 35%-controlled entity of a DTK?
Part IV F9_04_CONTR_NONCSH_MT_25K_X 29 Received > $25,000 in non-cash contributions?
Part IV F9_04_CONTR_ART_HIST_X 30 Received contributions of art, historical treasures, etc.?
Part VI F9_06_GVRN_NUM_VOTING_MEMB 1a Number of voting governing body members
Part VI F9_06_GVRN_NUM_VOTING_MEMB_IND 1b Number of independent voting members
Part VI F9_06_GVRN_DTK_FAMBIZ_RELATION_X 2 Family/business relationship among officers, directors, trustees, key employees?
Part VI F9_06_GVRN_DELEGATE_MGMT_DUTY_X 3 Delegation of management duties?
Part VI F9_06_GVRN_DOC_GVRN_BODY_X 8a Contemporaneous documentation of governing body meetings?
Part VI F9_06_POLICY_FORM990_GVRN_BODY_X 11a Form 990 provided to governing body?
Part VI F9_06_POLICY_COI_X 12a Conflict of interest policy?
Part VI F9_06_POLICY_COI_DISCLOSURE_X 12b Annual disclosure of interests?
Part VI F9_06_POLICY_COI_MONITOR_X 12c Regular monitoring and enforcement of COI policy?
Part VI F9_06_POLICY_WHSTLBLWR_X 13 Whistleblower policy?
Part VI F9_06_POLICY_DOC_RETENTION_X 14 Document retention and destruction policy?
Part VI F9_06_POLICY_COMP_PROCESS_CEO_X 15a Independent compensation process for CEO/top official?
Part VI F9_06_DISCLOSURE_AVBL_OTH_X 18 Governing documents available: other
Part VI F9_06_DISCLOSURE_AVBL_OTH_WEB_X 18 …on another organization’s website
Part VI F9_06_DISCLOSURE_AVBL_REQUEST_X 18 …upon request
Part VI F9_06_DISCLOSURE_AVBL_OWN_WEB_X 18 …on the organization’s own website
Part XII F9_12_FINSTAT_METHOD_ACC_ACCRU_X 1 Accounting method: accrual
Part XII F9_12_FINSTAT_METHOD_ACC_CASH_X 1 Accounting method: cash
Part XII F9_12_FINSTAT_METHOD_ACC_OTH 1 Accounting method: other (free text)
Schedule M SM_01_REVIEW_PROCESS_UNUSUAL_X 31 Review process for unusual noncash gifts?

For a full data dictionary see the irs990efile data dictionary. The tables themselves live in the NCCS efile v2.1 archive (https://nccs-efile.s3.us-east-1.amazonaws.com/public/efile_v2_1/{TABLE}-{YEAR}.CSV, years 2009–2024); browse them in the efile v2.1 catalog.