A technical working paper for this package can be found here.
Measure income and wealth inequality in R. Gini coefficients with confidence intervals, Theil indices, Atkinson indices, Palma ratios, Lorenz curves, poverty measures, tax progressivity, and more. All functions accept optional survey weights, and every measure now exposes bootstrap confidence intervals via ci = TRUE.
What’s new
0.2.1 fixes a side effect: iq_sample_data() reseeded the caller’s random number stream, so every later random draw in the session was reset to a fixed sequence. It now restores the caller’s state. No returned value changes.
0.2.0 responds to feedback from Frank Cowell and Emmanuel Flachaire on the v0.1.0 release.
-
Bootstrap CIs on every measure.
iq_theil,iq_atkinson,iq_sgini,iq_palma,iq_hoover,iq_kolm,iq_percentile_ratio,iq_polarisation,iq_shares,iq_concentration,iq_kakwani, andiq_povertyall gainci,R, andlevelarguments.iq_compare()runs a single bootstrap loop and propagates CIs to every row. -
Negative values supported. Gini, S-Gini, top shares, Palma, Hoover, Wolfson, Kakwani, and
iq_compare()acceptnegatives = "keep"for distributions containing negatives (wealth, post-tax income). -
Raffinetti et al. (2017) normalised Gini.
iq_gini(x, negatives = "keep", normalised = TRUE)rescales the index back into [0, 1] when negatives are present. -
Wagstaff correction added to
iq_concentrationalongside the existing Erreygers correction. -
iq_kakwanibug fix. The post-tax Gini no longer takes the absolute value of negative net incomes, so the Reynolds-Smolensky index is honest under high tax burdens.
Installation
install.packages("inequality")
# Development version
# install.packages("devtools")
devtools::install_github("charlescoverdale/inequality")Why this package?
The main CRAN package for inequality measurement (ineq) was last updated in 2014. It computes basic Gini and Theil indices but has no support for survey weights, no confidence intervals, no subgroup decomposition, no poverty measures, no Palma ratio, and no tax progressivity analysis.
inequality fills these gaps. You bring income or wealth data from any source (household surveys, tax records, administrative data, simulations) and the package handles measurement, decomposition, and comparison. Every function accepts optional weights, returns a clean S3 object with a print method, and cites the underlying academic paper.
Quick start
library(inequality)
# Built-in sample data: 1000 synthetic incomes
d <- iq_sample_data("income")
# How unequal is this distribution?
iq_gini(d$income)
#> -- Gini Coefficient ------------------------------------------------------------
#> * Gini: 0.43
#> * Observations: 1000
# With confidence intervals
iq_gini(d$income, ci = TRUE)
#> -- Gini Coefficient ------------------------------------------------------------
#> * Gini: 0.43
#> * Observations: 1000
#> * Bootstrap 95% CI: [0.407, 0.4542]What can it do?
Compare indices side by side
iq_compare(d$income)
#> -- Inequality Comparison (n = 1000) --------------------------------------------
#> * Gini 0.4300
#> * S-Gini (delta=3) 0.5627
#> * Theil T (GE1) 0.3307
#> * Theil L (GE0) 0.3241
#> * Atkinson (e=0.5) 0.1506
#> * Atkinson (e=1.0) 0.2768
#> * Kolm (a=1) 46736.2301
#> * Wolfson 0.1988
#> * Palma ratio 2.1528
#> * Hoover 0.3126
#> * P90/P10 7.8282
#> * P80/P20 3.9206Who gets what? Income shares
iq_shares(d$income)
#> -- Income Shares ---------------------------------------------------------------
#> * Bottom 50%: 21.2% of income (50% of population)
#> * P50-P90: 47.1% of income (40% of population)
#> * P90-P99: 24% of income (9% of population)
#> * Top 1%: 6.6% of income (1% of population)
#> * Observations: 1000Between-group vs within-group inequality
d <- iq_sample_data("grouped")
iq_decompose(d$income, d$group)
#> -- Between-Within Decomposition (Theil T (GE(1))) ------------------------------
#> * Total: 0.463
#> * Between: 0.116 (25.1%)
#> * Within: 0.347 (74.9%)
#>
#> -- Group Detail --
#>
#> * A: n=400, mean=31572, pop=40%, income=24.1%
#> * B: n=350, mean=44006, pop=35%, income=29.4%
#> * C: n=250, mean=97783, pop=25%, income=46.6%Poverty measurement
d <- iq_sample_data("income")
iq_poverty(d$income, line = 20000)
#> -- Poverty Measures (line = 20000) ---------------------------------------------
#> * Headcount (FGT0): 23.5%
#> * Poverty gap (FGT1): 0.0795
#> * Severity (FGT2): 0.0372
#> * Sen index: 0.1075
#> * Watts index: 0.1124
#> * Poor: 235 of 1000 observationsIs a tax progressive?
pre_tax <- d$income
tax <- pre_tax * (0.10 + 0.15 * (pre_tax / max(pre_tax)))
iq_kakwani(pre_tax, tax)
#> -- Fiscal Progressivity (Progressive) ------------------------------------------
#> * Kakwani index: 0.0646
#> * Reynolds-Smolensky index: 0.0092
#> * Pre-tax Gini: 0.43
#> * Post-tax Gini: 0.4208
#> * Tax concentration coefficient: 0.4946
#> * Average tax rate: 12.5%
#> * Observations: 1000Lorenz curve and growth incidence
# Lorenz curve
lc <- iq_lorenz(d$income)
plot(lc)
# Growth incidence curve
panel <- iq_sample_data("panel")
gic <- iq_growth_incidence(panel$income_t0, panel$income_t1)
plot(gic)Functions
Inequality indices
| Function | What it measures |
|---|---|
iq_gini() |
Gini coefficient (bootstrap or asymptotic CIs) |
iq_sgini() |
Extended Gini family (adjustable inequality aversion) |
iq_theil() |
Theil T, Theil L, and generalised entropy GE(alpha) |
iq_atkinson() |
Atkinson index (with equally distributed equivalent income) |
iq_kolm() |
Kolm index (absolute inequality, translation invariant) |
iq_palma() |
Palma ratio (top 10% share / bottom 40% share) |
iq_hoover() |
Hoover index (Robin Hood index, Pietra index) |
iq_percentile_ratio() |
P90/P10, P80/P20, or custom ratios |
Distribution and decomposition
| Function | What it measures |
|---|---|
iq_lorenz() |
Lorenz curve with plot method |
iq_shares() |
Income shares by quantile (top 1%, top 10%, etc.) |
iq_decompose() |
Between-within group decomposition (GE family) |
iq_concentration() |
Concentration index with optional Erreygers correction |
iq_polarisation() |
Wolfson bipolarisation index |
Poverty
| Function | What it measures |
|---|---|
iq_poverty() |
FGT family (headcount, gap, severity), Sen and Watts indices |
iq_growth_incidence() |
Growth incidence curve (is growth pro-poor?) |
Fiscal
| Function | What it measures |
|---|---|
iq_kakwani() |
Kakwani progressivity + Reynolds-Smolensky redistribution |
Utilities
| Function | What it does |
|---|---|
iq_compare() |
All major indices in one table |
iq_sample_data() |
Built-in synthetic data for examples |
Where to find inequality data
| Source | Coverage | R package |
|---|---|---|
| World Bank PIP | Global poverty and inequality | pipr |
| World Inequality Database | Top income shares, 100+ countries | wid |
| Luxembourg Income Study | Harmonised household surveys | lissyrtools |
| OECD Income Distribution | OECD member Gini, P90/P10, shares | readoecd |
| Eurostat EU-SILC | European household income | eurostat |
| UK Family Resources Survey | UK income distribution | Download CSV |
| US Current Population Survey | US income and poverty | ipumsr |
| UN WIDER WIID | Cross-country inequality database | Download CSV |
Related packages
| Package | Description |
|---|---|
| hmrc | UK income tax data (Income Tax by income range) |
| ato | Australian Taxation Office (income distributions) |
| ons | UK Office for National Statistics data (household income, ASHE) |
| ukhousing | UK Land Registry, EPC, and planning data (housing wealth) |
| ivcheck | IV diagnostics (for distributional treatment effects) |
| inflationkit | Inflation analysis (real-terms incomes) |
Issues
Report bugs or request features at GitHub Issues.