CPS_WAGE_BANDS

Build a national distribution of reported hourly wages from the Current Population Survey. Choose the wage-band boundaries, compare the observed distribution with a grouped gamma fit, and explore conditional minimum-wage staffing scenarios with a linear program.

Syntax

C=CPS_WAGE_BANDS(year,month,boundary1,boundary2,...)
EXTRACT(C,table)
EXTRACT(C,chart)
EXTRACT(C,fit)
EXTRACT(C,lp:oldFloor:newFloor[:all][:auto:cost:output:capacity][:budget:share])

Supply 1 to 20 strictly ascending boundaries in dollars per hour, specified to the cent. The command creates a first band from $0.01 to one cent below the first boundary and a last band from the final boundary through $99.99. Each boundary starts a new band. For example, 7.25,10,15 gives $0.01–$7.24, $7.25–$9.99, $10.00–$14.99, and $15.00–$99.99.

ArgumentMeaning
year, monthCPS Basic Monthly survey year and month. The implementation accepts years 1994–2100 and months 1–12; availability depends on the Census API.
boundary1,...Hourly-dollar cut points in ascending order. Include every proposed wage floor as an exact boundary when running an LP scenario.

The output counts national hourly-paid workers with valid positive reported hourly pay, weighted by PWORWGT. It uses the CPS hourly earnings field PTERNHLY. Salaried workers and records without valid positive hourly pay are outside this denominator. A server-side CENSUS_API_KEY is required; the key does not appear in a script.

Make and inspect the distribution

C=CPS_WAGE_BANDS(2025,8,5,7.25,10,12.5,15,17.5,18,20,22.5,25,30,35,40,45,50,60,70,80,90)
EXTRACT(C,table)
EXTRACT(C,chart)
EXTRACT(C,source)

table reports weighted workers and their percentage in each band. chart draws a grouped bar chart of those percentages. The final band is wide, so its bar represents a share of workers, not a probability density per dollar. source states the survey fields and denominator.

Fit the reported wage distribution

EXTRACT(C,fit)
EXTRACT(C,fit_table)
EXTRACT(C,fit_density)
EXTRACT(C,fit_counts)

fit produces one grouped bar chart with observed and fitted wage-band shares. The title reports the gamma shape, scale, and mean absolute band-share error in percentage points. The model fits interval probabilities to survey-weighted band counts, conditional on wages in the reported $0.01–$99.99 range; it does not pretend every worker earns a band midpoint. Use narrow bands to see where the smooth curve misses rounding, threshold bunching, or the upper tail.

How to read the fit. A fitted curve describes the observed distribution. It does not reconstruct wages without a wage floor and cannot by itself estimate an employment effect.

Explore a wage-floor scenario

The LP asks how many survey-weighted worker equivalents can be retained if a hypothetical old-floor payroll is held fixed while retained workers below a new floor must be paid at least that new floor. It maximizes retained worker equivalents subject to the specified payroll limit. Existing wages above the new floor remain at their assumed levels.

EXTRACT(C,lp:15:18)
EXTRACT(C,lp:15:18:all)
EXTRACT(C,lp:15:18:budget:0.01)
EXTRACT(C,lp:15:18:all:budget:0.02)
SuffixAssumption
lp:15:18Hypothetically pay everyone at least $15 in the baseline. Raise retained workers below $18 to $18. Keep workers in bands entirely above $18, and hold baseline hourly payroll fixed.
:allAllow employment in every band to adjust, including bands above the new floor. Their assumed wages do not fall.
:budget:0.01Permit hourly payroll to rise 1% above the hypothetical old-floor baseline. The share must be between 0 and 1.

Both floors must coincide with boundaries supplied to CPS_WAGE_BANDS. The output shows baseline and retained worker equivalents, payroll amounts, and a by-band allocation. It uses each band midpoint as its assumed wage because the source returns band counts rather than within-band wage totals. Every worker is assumed to supply the same hours.

Interpretation. The $15 baseline in this example is hypothetical: national reported wages include values below $15. A fixed national payroll is a scenario assumption, not a measured set of employer budgets. Fractional worker equivalents and by-band reductions are optimizer allocations, not predicted layoffs. Several below-floor bands can have identical post-policy cost, so their individual allocations may be arbitrary even when total retention is stable.

Optional automation capacity

EXTRACT(C,lp:15:18:auto:10:2:0.20)
EXTRACT(C,lp:15:18:all:auto:10:2:0.20)
EXTRACT(C,lp:15:18:auto:10:2:0.20:budget:0.01)

auto:10:2:0.20 assumes $10 per machine-hour, output equivalent to two human hours per machine-hour, and machine capacity of at most 0.20 hours per baseline human hour. In this variant, human plus machine output must reach baseline output. The three numbers are illustrative inputs, not CPS measurements. Automation is divisible rented capacity; the model does not include purchase, maintenance, installation, training, or task-specific constraints. An infeasible set of assumptions returns a message instead of a solution.

Sensitivity matters. Compare budget:0, budget:0.01, budget:0.02, and budget:0.03. A small permitted payroll increase can change the optimum substantially; full retention becomes feasible once the allowed payroll covers the new-floor cost.

Extractable results

EXTRACT keyResult
slideshowSummary, observed wage chart, and source information. SLIDESHOW(C) also works.
table or summaryHTML table of bands, weighted counts, and shares.
chart or histogramGrouped bar chart of observed band shares.
countsMatrix columns: lower wage, upper wage, weighted count.
sharesMatrix columns: lower wage, upper wage, fraction of included workers.
fitSingle chart comparing observed and grouped gamma fitted shares. Aliases: fitted, fit_gamma.
fit_tableGamma parameters and observed versus fitted shares by band.
fit_densityObserved band-share densities against the conditional gamma density.
fit_countsMatrix columns: lower wage, upper wage, observed count, fitted count.
lp:old:new...HTML summary and by-band table for the chosen LP scenario.
source or metadataSurvey fields, population definition, and source link.

Complete short example

C=CPS_WAGE_BANDS(2025,8,5,7.25,10,12.5,15,17.5,18,20,22.5,25,30,35,40,45,50,60,70,80,90)
EXTRACT(C,chart)
EXTRACT(C,fit)
EXTRACT(C,lp:15:18)
EXTRACT(C,lp:15:18:budget:0.02)
EXTRACT(C,source)

Each command occupies one line. Data: U.S. Census Bureau, CPS Basic Monthly microdata API documentation. For a full analysis with scenario comparisons, see the saved RainbowStats simulation.