Home · Command reference

RainbowStats™ · Command reference

Matched Comparison

Compare outcomes above and below a threshold after pairing observations with similar measured characteristics.

MATCHED_COMPARISON performs one-to-one matching without replacement. A selected variable defines the two groups; the remaining covariates determine which observations are paired. The result shows outcome differences, covariate balance and the individual matches.

Quick start: compare labor-market conditions

m = MATCHED_COMPARISON(LIST(SERIES_SINCE(UNRATE,20010101),SERIES_SINCE(JTSJOR,20010101),SERIES_SINCE(TCU,20010101)),1,4)
EXTRACT(m,"slideshow")

Run this example in RainbowStats

This monthly example compares unemployment in observations where the job openings rate exceeds 4% with unemployment in observations where the rate is at or below 4%. It matches on capacity utilization, using the common date range from January 2001 onward.

List positionSeriesRole
0UNRATEOutcome: unemployment rate.
1JTSJORGroup variable: job openings rate; selected by groupColumn = 1.
2TCUMatching covariate: capacity utilization.
A descriptive comparison. A positive difference means unemployment is higher in the matched above-threshold observations; a negative difference means it is lower. Matching on capacity utilization alone does not establish that job openings cause unemployment to change.

MATCHED_COMPARISON — Syntax and column roles

m = MATCHED_COMPARISON(seriesList,groupColumn,threshold)
m = MATCHED_COMPARISON(seriesList,groupColumn,threshold,caliper)
ArgumentMeaning
seriesListA data-series list, normally built with LIST. Requires at least three series: an outcome, a group variable and one matching covariate.
groupColumnZero-based position of the group variable. Must be an integer from 1 through the last list position. Position 0 is reserved for the outcome.
thresholdA finite numeric cutoff in the group variable’s units. Values strictly greater than the cutoff form the above-threshold group; values at or below form the control group.
caliperOptional positive maximum matching distance. The three-argument form has no distance cutoff. A finite caliper includes candidate pairs whose distance is equal to the cutoff.

The outcome is always column 0. Every other column except groupColumn becomes a matching covariate. There is no separate argument listing matching columns, and no constant is automatically added.

m = MATCHED_COMPARISON(LIST(outcome,group,x1,x2),1,threshold,caliper)
m = MATCHED_COMPARISON(LIST(outcome,x1,group,x2),2,threshold,caliper)

These schematic forms show the same roles in different list positions. Replace the named series and numeric arguments with your own values. The selected group variable and the outcome are excluded from the matching distance.

A binary group indicator also works: with values 0 and 1, a threshold of 0.5 assigns 1 to the above-threshold group and 0 to controls. For percentage-valued series such as JTSJOR, a threshold of 4 means 4%, not 0.04.

How observations are matched

  1. Prepare the common range. The operator calls getSameDateRange(), constructs the data matrix and discards rows with nonfinite values in any input column.
  2. Form the groups. Complete observations with a group value above the threshold enter the above-threshold group; all other complete observations enter controls.
  3. Scale each covariate. Calculate its sample standard deviation across all complete observations from both groups together. Covariates with standard deviation at or below 1e-12 are ignored in distance calculations.
  4. Construct candidate pairs. Calculate a standardized distance for every above-threshold/control combination. Keep candidates at or inside the caliper, if supplied.
  5. Choose pairs greedily. Sort all retained candidates by ascending distance. Accept a pair only when neither observation has already been used. Ties are broken by the original above-threshold row index and then the control row index.
  6. Display the matches. Sort accepted pairs by the above-threshold observation’s date and then its original row index. Compute outcome differences and diagnostics.

Exact distance and caliper units

For q active matching covariates, the distance is:

distance(i,j) = sqrt( sum over k of [ (x[i,k] - x[j,k]) / s[k] ]² / q )

Here s[k] is the sample standard deviation of covariate k across the full cleaned sample. This is a root-mean-square standardized difference. It is the ordinary standardized Euclidean distance divided by sqrt(q); covariate correlations are not used.

With one active covariate, a caliper of 0.25 permits an absolute difference of up to one quarter of its full-sample standard deviation. With several covariates, the limit applies to the combined root-mean-square distance, not separately to every covariate.

Greedy matching without replacement. Each observation can appear in at most one pair. Sorting all candidates does not solve a global minimum-total-distance assignment. With a caliper, the greedy choices can also leave fewer matches than another feasible assignment.

Without a caliper, the number of pairs reaches the smaller group’s size. With a finite caliper, some observations in either group may remain unmatched. Tightening the caliper changes both the sample being compared and the quality of accepted matches.

Dates do not enter the distance. An observation can match to an earlier or later period, potentially years away. The operator imposes no temporal window, exact-match condition, propensity-score model or chronological restriction.

What the default output shows

Displaying m, or extracting slideshow, returns these five panels in order:

PanelContents
Matched Comparison SummaryOutcome and units; group variable and threshold rules; covariate count and caliper; complete group counts, matched and unmatched counts; match rate; matched outcome means, average difference, standard error, t-statistic, approximate 95% bounds and average distance.
Covariate BalanceEach matching covariate’s standardized mean difference before and after matching and improvement in absolute imbalance.
Matched Outcomes by PairTwo outcome lines: “Above Threshold” and “Matched At or Below.”
Matched Outcome DifferencesOne line showing above-threshold outcome minus its matched control outcome.
Matched PairsPair number, both dates, distance, both outcomes and paired difference.

The chart x-axis is pair number. It is not calendar time. Pairs are ordered by the above-threshold date, while their control dates may be in a different order. Consult the pair table to inspect the actual dates. Group means in the summary refer to the matched observations; group counts describe the complete eligible observations before matching.

EXTRACT — Results, charts and scalar statistics

EXTRACT(m,"extract_name")

The operator trims surrounding whitespace and converts names to lowercase. The following 14 result types support 22 names including aliases.

All supported matched-comparison extracts
Primary nameAliasReturnsMeaning
modelsummarySummary tableGroup rules and counts, matched means, average difference, uncertainty, match rate and average distance.
slideshow—Five-panel slideshowSummary, balance, matched outcomes, paired differences and matched-pair table.
balancebalance_modelBalance tableSigned standardized mean differences before and after matching, and percentage improvement in absolute imbalance.
pairsmatched_pairs_modelMatched-pair tablePair number, above-threshold date, control date, distance, both outcomes and their difference.
paired_chartmatched_outcomesLine chartAbove-threshold and matched-control outcomes by matched-pair number.
differencesdifference_chartLine chartAbove-threshold outcome minus control outcome for each matched pair. Returns a chart, not a data series.
effectaverage_differenceNumberMean paired outcome difference, in the outcome’s units.
std_errorstandard_errorNumberPaired standard error of the mean difference; no HAC or cluster adjustment.
t_statt_statisticNumberMean difference divided by its paired standard error, when defined.
lower_ci—NumberLower approximate 95% confidence bound, using the normal multiplier 1.959963984540054.
upper_ci—NumberUpper approximate 95% confidence bound, using the same normal multiplier.
match_rate—Number100 × matched pairs / complete above-threshold observations. This is a percentage, not a fraction.
matched_pairs—NumberNumber of matched pairs; distinct from pairs, which returns the pair table.
average_distance—NumberMean standardized matching distance across accepted pairs.
Similar names return different things. pairs returns a table, while matched_pairs returns a count. differences returns a chart. There is no raw difference-series, raw matched-series, coefficient-array or p-value extract in this implementation.

Examples: calipers, multiple covariates and extracts

Apply a matching caliper

m = MATCHED_COMPARISON(LIST(SERIES_SINCE(UNRATE,20010101),SERIES_SINCE(JTSJOR,20010101),SERIES_SINCE(TCU,20010101)),1,4,0.25)
EXTRACT(m,"slideshow")

This repeats the quick start with a maximum distance of 0.25. Inspect the match rate, unmatched counts, balance table and average distance before interpreting the outcome difference.

Use two matching covariates

outcome = SERIES_SINCE(UNRATE,20010101)
group = SERIES_SINCE(JTSJOR,20010101)
capacity = SERIES_SINCE(TCU,20010101)
inflation = DIFF(SERIES_SINCE(CPIAUCSL,20010101))
m = MATCHED_COMPARISON(LIST(outcome,group,capacity,inflation),1,4,0.25)
EXTRACT(m,"slideshow")

Capacity utilization and the monthly absolute change in the CPI index determine the matches. DIFF(CPIAUCSL) measures an index-point change, not a percentage inflation rate. Additional covariates should follow the question being studied; adding variables does not automatically improve a comparison.

Build a focused presentation

m = MATCHED_COMPARISON(LIST(SERIES_SINCE(UNRATE,20010101),SERIES_SINCE(JTSJOR,20010101),SERIES_SINCE(TCU,20010101)),1,4,0.25)
SLIDESHOW(EXTRACT(m,"summary"),EXTRACT(m,"balance"),EXTRACT(m,"paired_chart"),EXTRACT(m,"difference_chart"),EXTRACT(m,"pairs"))

Retrieve individual statistics

m = MATCHED_COMPARISON(LIST(SERIES_SINCE(UNRATE,20010101),SERIES_SINCE(JTSJOR,20010101),SERIES_SINCE(TCU,20010101)),1,4,0.25)
effect = EXTRACT(m,"effect")
se = EXTRACT(m,"std_error")
t = EXTRACT(m,"t_stat")
low = EXTRACT(m,"lower_ci")
high = EXTRACT(m,"upper_ci")
rate = EXTRACT(m,"match_rate")
count = EXTRACT(m,"matched_pairs")
distance = EXTRACT(m,"average_distance")

Display the scalar of interest as the final equation, or use EXTRACT(m,"summary") for a labeled overview. The default three-argument example and all 22 extract names were checked in live RainbowStats calls.

Outcome differences and uncertainty

For each accepted pair, the difference is the above-threshold outcome minus its matched control outcome. With n pairs:

d[i] = outcome_above[i] - outcome_control[i]
average_difference = sum(d[i]) / n
s_d² = sum((d[i] - average_difference)²) / (n - 1)
standard_error = sqrt(s_d² / n)
t_statistic = average_difference / standard_error
approximate_95%_interval = average_difference ± 1.959963984540054 × standard_error

The average difference has the outcome’s units. For an unemployment rate expressed in percent, the difference is in percentage points. The paired standard error uses variation in differences across the accepted pairs.

The interval uses a normal critical value, not a finite-sample Student-t critical value. The reported “Paired T-stat” is the difference-to-standard-error ratio; the command does not return a p-value.

Time-series dependence matters. The paired standard error does not adjust for serial correlation, clustering, the matching-selection process or uncertainty in covariate scaling. With serially dependent monthly or daily data, the nominal interval may overstate precision. This operator provides no HAC option.

A single accepted pair produces an average difference but undefined standard error, t-statistic and confidence bounds. If the standard error is at or below 1e-12, the t-statistic is undefined. With multiple pairs and exactly zero variance in differences, the calculated interval collapses to the mean difference.

Causal interpretation requires a design. The code’s “treated” label means above threshold. It does not establish an intervention, random assignment or a treatment effect. Consider unmeasured confounding, overlap, timing, selection and whether matching variables are appropriate pre-treatment characteristics. A caliper can restrict the result to a selected subset of above-threshold observations.

Read the covariate-balance table

Balance diagnostics cover matching covariates only. The outcome and the group-defining variable are excluded.

SMD = (mean_above - mean_control) / sqrt((variance_above + variance_control) / 2)
improvement_% = 100 × (abs(SMD_before) - abs(SMD_after)) / abs(SMD_before)

Each variance is a sample variance within its respective group. The “before” SMD uses all complete observations in each group. The “after” SMD uses the accepted matched observations and recomputes the denominator from those matched groups.

Consequently, this balance denominator differs from the full-sample standard deviation used in matching distance. The matched SMD also uses a different sample and potentially a different scale from the pre-match SMD.

The summary’s matching-covariate count includes all designated matching columns, even covariates ignored in distance calculations because their full-sample standard deviation is negligible.

Data preparation, limits and errors

ConditionBehavior or remedy
Fewer than three seriesSupply an outcome, a group variable and at least one matching covariate.
Invalid group columnUse a zero-based integer from 1 through the last list position. Column 0 cannot define the groups.
Nonfinite thresholdUse a finite numeric cutoff.
Zero, negative or NaN caliperUse a strictly positive finite value, or omit the fourth argument for unrestricted matching.
No usable observationsInspect date coverage and missing/nonfinite values across every input series. Rows must be complete across the list.
Threshold leaves one group emptyChoose a cutoff with eligible observations on both sides. Equality belongs to controls.
Every matching covariate is constantSupply at least one matching covariate whose cleaned-sample standard deviation exceeds 1e-12.
More than 2,000,000 candidate combinationsThe limit is above_count × control_count, calculated before caliper filtering. Clip the date range or aggregate the series; a tighter caliper alone does not avoid this check.
No pairs within caliperWiden the caliper or reconsider sample overlap and covariate choices. The command returns an error rather than an empty comparison.

Use series with compatible frequencies and observation timing. The command aligns the common range, but it does not automatically choose aggregation rules or verify the economic timing of each variable. Review missing periods and source definitions before interpreting a match.

Inspect both dates in the pair table, especially when matching time-series observations across long histories. The algorithm has no built-in exclusion for crises, policy changes, seasons or other regimes. Restrict the sample deliberately when those distinctions matter.