Post-Depreciation Profitability Margin
Source:R/get-profit-margin-postdepr.R
get_profit_margin_postdepr.RdOperating surplus or deficit as a share of total revenue, after depreciation.
Formula:
podpm = ( total_revenue - total_expenses ) / total_revenueDefinitional Range
Bounded above at 1.0; unbounded below. The typical range for nonprofits is approximately [-0.30, 0.30]. Extreme negative values may reflect major write-downs or one-time capital expenses.
Benchmarks and rules of thumb
Near zero: Normal for nonprofits operating close to break-even.
0.02-0.07 (2-7%): Healthy.
Below -0.05 for two or more consecutive years: Common vulnerability threshold.
A persistent gap between post- and pre-depreciation margins signals capital consumption requiring future capital expenditure.
Calculated For: 990 filers only.
Usage
get_profit_margin_postdepr( df,
expenses = "F9_09_EXP_TOT_TOT",
revenue = "F9_08_REV_TOT_TOT",
winsorize = 0.98 ,
range = "np",
sanitize = TRUE,
summarize = FALSE )Arguments
- df
A
data.framecontaining the fields required for computing the metric.- expenses
Total functional expenses.
- revenue
Total revenue.
- winsorize
The winsorization value (between 0 and 1), defaults to 0.98, which winsorizes at the 1st and 99th percentiles.
- range
Character string specifying the theoretical range of the ratio, used to set winsorization bounds. Default
"np". Options:"np"(negative to positive),"zp"(zero to positive),"zo"(zero to one),"nz"(negative to zero), or a custom"lo;hi"pair (e.g."0;10").- sanitize
Logical (default
TRUE). IfTRUE, NA values in the financial input columns are imputed to zero before the ratio is computed, respecting form scope: Part X and VIII/IX fields (990 only) are imputed only for 990 filers; Part I summary fields (990 + 990EZ) are imputed for all filers. The returned dataframe always contains the original unmodified input columns.- summarize
Logical. If
TRUE, prints asummary()of the results and plots density curves for all four output columns (raw, winsorized, z-score, percentile). Defaults toFALSE.
Value
Object of class data.frame: the original dataframe appended with four
new columns:
- `profit_postdepr` - post-depreciation profitability margin (raw)
- `profit_postdepr_w` - winsorized version
- `profit_postdepr_z` - standardized z-score (based on winsorized values)
- `profit_postdepr_p` - percentile rank (1-100)Details
Primary uses and key insights
The post-depreciation profit margin measures the operating surplus or deficit as a share of total revenue, using expenses that include depreciation charges. It is the most conservative profit margin measure because depreciation, while non-cash, represents the consumption of capital assets that will eventually require replacement.
This measure is closely related to get_surplus_margin_ratio() but uses
Part VIII revenue and Part IX expenses directly (both 990-only, PC scope) rather
than the Part I summary line, making it more precise but narrower in coverage.
Formula variations and their sources
(Total revenue - Total expenses) / Total revenue, using Part VIII line 12A and Part
IX line 25A. The pre-depreciation version (get_profit_margin_predepr())
adds back depreciation to better approximate cash flow. The PODPM is also called
the operating margin in some sources.
Canonical citations
Tuckman, H.P. & Chang, C.F. (1991). A methodology for measuring the financial vulnerability of charitable nonprofit organizations. Nonprofit and Voluntary Sector Quarterly, 20(4), 445-460.
Keating, E.K., Fischer, M., Gordon, T.P. & Greenlee, J. (2005). Assessing financial vulnerability in the nonprofit sector. Harvard Business School Working Paper 04-016.
Examples
library( fiscal )
data( dat10k )
d <- get_profit_margin_postdepr( df = dat10k )
#> :: Revenue equal to zero :: 74 case(s) replaced with NaN
head( d[ , c( "profit_postdepr", "profit_postdepr_w", "profit_postdepr_z", "profit_postdepr_p" ) ] )
#> profit_postdepr profit_postdepr_w profit_postdepr_z profit_postdepr_p
#> <num> <num> <num> <int>
#> 1: NA NA NA NA
#> 2: 0.06874629 0.06874629 -0.1467868 45
#> 3: 0.07802226 0.07802226 -0.1040122 46
#> 4: NA NA NA NA
#> 5: -0.16428532 -0.16428532 -1.1547537 14
#> 6: NA NA NA NA