## Understanding weight calculations in psmatch2

Propensity score matching implicitly weighs the matched treated observations to compute counterfactual outcomes.

The Stata command `-psmatch2-` stores these weights in a variable called `_weight`.

Someone pointed me to an old blog post somewhere on the Internet, which shows that there may be some confusion about what these weights are and where they come from.

K-neighbor matching estimates the counterfactual outcome for a treated observation by averaging the outcomes of its `K` matches.

This means that every time an untreated observation is matched to a treated observation (and this can happen more than once when matching with replacement), it is used with “weight” `1/K` since one is dividing by `K` when averaging.

If one uses a caliper (i.e. excludes matches that are farther away than a minimum distance called a “caliper”) it can happen that some matches involve less than `K` neighbors

So more generally the weight is not `1/K` but rather `1/nr-of-matches`

(-psmatch2- saves the nr of matches for a given treated observation in the variable `_nn`)

The variable `_weight` sums these weights every time a control observation is used to construct a counterfactual outcome.

So let’s say that we are matching two treated observations to two neighbors with a caliper.

Then we may have that the first treated has two matches and the second treated only one match as in the following:

``````_id _treated _n1 _n2 _nn
1        1   3   4   2
2        1   3   .   1
3        0   .   .   .
4        0   .   .   .
``````

The matched outcome for the first treated will be averaged across observations 3 and 4 and these have thus each weight 1/2 here.

The matched outcome for the second treated obs will be averaged across observation 3 and which thus has weight 1.

Note that in each case the weights equal `1/_nn`.

Putting this together we can compute how often each matched untreated observation is used to construct the overall average counterfactual outcome by summing their weights:

``````_id _weight
3     1.5
4     0.5
``````

For the example in the blog-post above the following code shows that this indeed gives the weights in the variable `_weight`:

``````webuse cattaneo2, clear
set seed 795
g x=uniform()
sort x
psmatch2 mbsmoke prenatal1 fbaby mmarried medu fedu mage fage mrace frace, out(bweight) neighbor(5) caliper(.0295236) logit
tab _weight
rename _n* N* // otherwise reshape complains
reshape long N, i(_id) j(matchnr)
g altweight = 1 / Nn
collapse (sum) altweight, by(N)
tab altweight
``````

The weights in `_weight` are therefore not specific to `-psmatch2-`, but they follow directly from the definition of a `K`-neighbor matching estimator (independently of whether one matches on the propensity score or something else).