# How are weights computed in R matchit() function for full matching?

In the example I have, a small number of treated subjects are matched to a large number of untreated controls. I used

match= matchit(treat ~ SEX + ageint + bAVAL1 + bAVAL2, method = "full", caliper=0.3,
exact  = c("SEX", "ageint"), data = data)


It makes sense that the treated subjects have weight=1. Why do the multiple control subjects matched to each treated subject have weights>1?

     weights          subclass
1    1.0000000        1
2    2.0421053        1
3    2.0421053        1
4    2.0421053        1
5    2.0421053        1
6    2.0421053        1
7    1.0000000        2
8    2.5526316        2
9    2.5526316        2
10   2.5526316        2
11   2.5526316        2
12   1.0000000        3
13   2.5526316        3
14   2.5526316        3
15   2.5526316        3
16   2.5526316        3


This is explained in the documentation for matchit().

[E]ach unit is assigned to a subclass, which represents the pair they are a part of (in the case of k:1 matching) or the stratum they belong to (in the case of exact matching, coarsened exact matching, full matching, or subclassification). The formula for computing the weights depends on the argument supplied to estimand. A new stratum "propensity score" (p) is computed as the proportion of units in each stratum that are in the treated group, and all units in that stratum are assigned that propensity score. Weights are then computed using the standard formulas for inverse probability weights: for the ATT, weights are 1 for the treated units and p/(1-p) for the control units; for the ATC, weights are (1-p)/p for the treated units and 1 for the control units; for the ATE, weights are 1/p for the treated units and 1/(1-p) for the control units.

...

In each treatment group, weights are divided by the mean of the nonzero weights in that treatment group to make the weights sum to the number of units in that treatment group.

• Thanks. Sorry I overlooked this document. Since the weight for treated is 1. It should be ATT. The weight for untreated is p/(1-p). Since p is small. The weights for untreated are expected to be a small number <1 based on this formula. This description seems for 1: k fixed ratio matching. For full matching with a caliper, it is more like variable ratio matching. p should not be the same for each matched cluster. I still cannot make sense of the large weights for untreated I see.
– hehe
Jul 27, 2021 at 21:02
• You may be missing the part where it says "In each treatment group, weights are divided by the mean of the nonzero weights in that treatment group to make the weights sum to the number of units in that treatment group." You can try calculating the weights manually using the formula I gave (including this final step) and see that the results are correct.
– Noah
Jul 28, 2021 at 1:31
• p <- rep(0, n); for (i in unique(subclass)) {p[subclass == i] <- mean(treat[subclass == i] == 1)}; w <- ifelse(treat == 1, 1, p/(1-p)); w[treat == 0] <- w[treat == 0]/mean(w[treat == 0]) That all it is. The code works regardless of whether it's k:1 matching or not.
– Noah
Jul 28, 2021 at 1:36