Skip to contents

Impute zero for NA values in IRS 990 financial fields, respecting the distinction between fields available to all filers (990 + 990EZ) and fields that only appear on the full 990 form.

Usage

sanitize_financials(df, pz_vars = NULL, pc_vars = NULL)

Arguments

df

A data.frame containing IRS 990 efile financial fields. Should contain a RETURN_TYPE column (values "990" or "990EZ") for accurate filer-type detection. If absent, filer type is inferred from field availability.

pz_vars

Optional character vector of PZ-scope column names (present on both 990 and 990EZ). When supplied, the local scope-aware imputer is used with exactly these fields. When NULL (default), scope is resolved from panel990 via panel990::panel_normalize().

pc_vars

Optional character vector of PC-scope column names (full 990 only). When supplied, imputation is restricted to 990 filers for these fields. When NULL (default), scope is resolved from panel990.

Value

A data.frame identical in structure to df, with NA values replaced by zero in the applicable financial columns. The original df is not modified.

Details

In IRS 990 efile data, organizations often leave financial line items blank when the value is zero rather than explicitly reporting zero. These blanks are typically encoded as NA in processed datasets. For ratio calculations this is problematic: a nonprofit with no investment income genuinely has a zero in that field, not a missing value.

sanitize_financials() corrects this by imputing zero for NA values in financial fields, subject to an important constraint: fields that only exist on the full 990 form (Part VIII, IX, and X) should not be imputed to zero for 990EZ filers, since those fields simply don't exist on the EZ form. Fields from Part I (the summary section) appear on both forms and can be safely imputed for all filers.

Filer type is determined from the RETURN_TYPE column when present ("990" = full filer, "990EZ" = short-form filer). If RETURN_TYPE is absent, filer type is inferred: rows with Part I data but missing Part VIII data are treated as 990EZ filers.

As of the panel990 portage, the default path delegates to panel990::panel_normalize(), which applies the same form-scoped, non-filer- protected zero imputation over the shared concordance-derived field scopes. Supplying pz_vars/pc_vars explicitly falls back to the local imputer for backward compatibility.

Examples

library( fiscal )
data( dat10k )

# Sanitize the full dataset before computing ratios
dat_clean <- sanitize_financials( dat10k )

# All ratios can then be computed without worrying about NA/zero ambiguity
dat_clean <- get_grants_govt_ratio( dat_clean )
#>    :: Total revenue equal to zero :: 74 case(s) replaced with NaN
dat_clean <- get_program_expenses_ratio( dat_clean )
#>    :: Total expenses equal to zero :: 207 case(s) replaced with NaN