Matching Methods for Causal Inference

ADAT Working Group

1 Preamble

Text from this notebook has been adopted from:

2 Premise

The “fundamental problem of causal inference” (Holland, 1986) is that, for each individual, we can observe only one of the potential outcomes, because each unit (each individual at a particular point in time) will receive either treatment or control, not both. The estimation of causal effects can thus be thought of as a missing data problem (Rubin, 1976a), where we are interested in predicting the unobserved potential outcomes.

2.1 Why?

To limit bias in estimation of treatment effect, we would like to compare treated and control groups that are as similar as possible

To estimate unobserved potential outcomes, we would like to compare treated and control groups that are as similar as possible. If the groups are very different, the prediction of Y (1) for the control group will be made using information from individuals who look very different from themselves, and likewise for the prediction of Y (0) for the treated group. A number of authors, including Cochran and Rubin (1973); Rubin (1973a,b, 1979); Heckman et al. (1998b); Rubin and Thomas (2000), and Rubin (2001), have shown that methods such as linear regression adjustment can actually increase bias in the estimated treatment effect when the true relationship between the covariate and outcome is even moderately non-linear, especially when there are large differences in the means and variances of the covariates in the treated and control groups.

2.2 Matching

Matching is a general approach for ensure “balance” of covariates between groups

Randomized experiments use a known randomized assignment mechanism to ensure “balance” of the covariates between the treated and control groups: The groups will be only randomly different from one another on all covariates, observed and unobserved. In non-experimental studies, we must posit an assignment mechanism, which determines which individuals receive treatment and which receive control.

A key assumption in non-experimental studies is that of strongly ignorable treatment assignment (Rosenbaum and Rubin, 1983b) which implies that (1) treatment assignment (T) is independent of the potential outcomes (Y (0), Y (1)) given the covariates (X): T ⊥ Y (0), Y (1))|X, and (2) there is a positive probability of receiving each treatment for all values of X: 0 < P(T = 1|X) < 1 for all X. The first component of the definition of strong ignorability is sometimes termed “ignorable,” “no hidden bias,” or “unconfounded.” Weaker versions of the ignorability assumption are sufficient for some quantities of interest, discussed further in Imbens (2004).

2.2.1 Types of matching and corresponding estimands

drawing

drawing

2.2.2 Fundamental Steps for Matching

Matching methods have four key steps, with the first three representing the “design” and the fourth the “analysis:”

  1. Defining “closeness”: the distance measure used to determine whether an individual is a good match for another,

  2. Implementing a matching method, given that measure of closeness,

  3. Assessing the quality of the resulting matched samples, and perhaps iterating with Steps (1) and (2) until well-matched samples result, and

  4. Analysis of the outcome and estimation of the treatment effect, given the matching done in Step (3).

The next four sections go through these steps one at a time, providing an overview of common approaches.

3 Data & Study Population

3.1 Study Summary

drawing

3.2 Objective

Estimate causal effect of antiviral therapy

  • Y = CD4 count at visit 8
  • A = 1 if received cART at visit 7, 0 if not
  • V1 = CD4 count at visit 7
  • V2 = HIV symptom score at visit 7

3.3 Data

HERS.df = read.table("https://sites.google.com/a/brown.edu/eldoret-short-course-2014/HERS_sample.dat", header=TRUE)
skimr::skim(HERS.df)
Data summary
Name HERS.df
Number of rows 357
Number of columns 6
_______________________
Column type frequency:
numeric 6
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
cd4cnt 0 1 281.11 163.45 1 159 271 385 781 ▆▇▇▂▁
haart 0 1 0.31 0.46 0 0 0 1 1 ▇▁▁▁▃
haart_1 0 1 0.19 0.39 0 0 0 0 1 ▇▁▁▁▂
cd4ct_1 0 1 264.02 132.67 0 163 263 381 499 ▅▇▇▇▆
symp_1 0 1 0.62 0.98 0 0 0 1 4 ▇▂▁▁▁
id 0 1 185.12 106.90 1 93 185 277 370 ▇▇▇▇▇

4 EDA

4.1 Variable Definitions & Notation

  • TX groups (A): HAART
  • Outcome (Y): 8th CD4 count
  • Covariates (V): Symptoms, 7th CD4 count

4.2 Mean of covariates between Tx groups

HERS = HERS.df
R = 1 - is.na(HERS$haart)
HERS = HERS[R==1,]

# dataset for analysis
Y = HERS$cd4cnt
A = HERS$haart
V = cbind(HERS$symp_1, HERS$cd4ct_1)
HERS = cbind(HERS, cbind(Y,A,V))
HERS = HERS[,6:10]

attach(HERS)

n = nrow(HERS)

# compare means between two treatment groups
paste0('Mean A==0: ', apply(V[A==0,], 2, mean, na.rm=T))
## [1] "Mean A==0: 0.585365853658537" "Mean A==0: 270.536585365854"
paste0('Mean A==1: ', apply(V[A==1,], 2, mean, na.rm=T))
## [1] "Mean A==1: 0.684684684684685" "Mean A==1: 249.585585585586"

4.3 Comparison between two treatment groups

No Covariate adjustment done

# comparison between two treatment groups
Y.null.model = glm(Y ~ A)
summary(Y.null.model)
## 
## Call:
## glm(formula = Y ~ A)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -281.79  -124.10    -7.79   104.90   502.90  
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  278.102     10.432  26.659   <2e-16 ***
## A              9.691     18.708   0.518    0.605    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for gaussian family taken to be 26771.13)
## 
##     Null deviance: 9510934  on 356  degrees of freedom
## Residual deviance: 9503751  on 355  degrees of freedom
## AIC: 4656.8
## 
## Number of Fisher Scoring iterations: 2

4.4 Standard regression adjustment

Covariate adjustment done

Y.reg.model = glm(Y ~ A + V)
summary(Y.reg.model)
## 
## Call:
## glm(formula = Y ~ A + V)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -258.38   -54.34    -9.73    49.54   512.95  
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   7.3385    12.3833   0.593  0.55382    
## A            30.9923    10.9144   2.840  0.00478 ** 
## V1           -2.2990     5.1609  -0.445  0.65626    
## V2            1.0058     0.0381  26.399  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for gaussian family taken to be 9043.855)
## 
##     Null deviance: 9510934  on 356  degrees of freedom
## Residual deviance: 3192481  on 353  degrees of freedom
## AIC: 4271.3
## 
## Number of Fisher Scoring iterations: 2

5 Matching

Matching methods have four key steps, with the first three representing the “design” and the fourth the “analysis:”

  1. Defining “closeness”: the distance measure used to determine whether an individual is a good match for another,

  2. Implementing a matching method, given that measure of closeness,

  3. Assessing the quality of the resulting matched samples, and perhaps iterating with Steps (1) and (2) until well-matched samples result, and

  4. Analysis of the outcome and estimation of the treatment effect, given the matching done in Step (3).

The next four sections go through these steps one at a time, providing an overview of common approaches.

5.1 Step 1: Define measure of closeness

drawing

FAQ:

Although exact matching is in many ways the ideal (Imai et al., 2008), the primary difficulty with the exact and Mahalanobis distance measures is that neither works very well when X is high dimensional. Requiring exact matches often leads to many individuals not being matched, which can result in larger bias than if the matches are inexact but more individuals remain in the analysis (Rosenbaum and Rubin, 1985b).

5.1.1 Propensity score model

Propensity scores summarize all of the covariates into one scalar: the probability of being treated. The propensity score for individual i is defined as the probability of receiving the treatment given the observed covariates: ei(Xi) = P(Ti = 1|Xi). Any model relating a binary variable to a set of predictors can be used. The most common for propensity score estimation is logistic regression, although non-parametric methods such as boosted CART and generalized boosted models (gbm) often show very good performance (McCaffrey et al., 2004; Setoguchi et al., 2008; Lee et al., 2009).

Recall that e(V1, V2) = P(A = 1 | V1, V2). The model specification is given by

logit{e(V1, V2)} = γ0 + γ1V1 + γ2V2

# fit propensity score model using logistic regression
ps.model = glm(A ~ V, family=binomial)
summary(ps.model)
## 
## Call:
## glm(formula = A ~ V, family = binomial)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.0782  -0.8795  -0.8101   1.4483   1.6807  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)  
## (Intercept) -0.5514019  0.2619477  -2.105   0.0353 *
## V1           0.0978251  0.1144259   0.855   0.3926  
## V2          -0.0011779  0.0008661  -1.360   0.1738  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 442.56  on 356  degrees of freedom
## Residual deviance: 439.93  on 354  degrees of freedom
## AIC: 445.93
## 
## Number of Fisher Scoring iterations: 4

5.1.2 Propensity scores distribution

# propensity scores

p.score = fitted(ps.model)

df=tibble(Y=Y,A=as.factor(A),V=V,p.score=p.score)
head(df , 10 )
## # A tibble: 10 × 4
##        Y A     V[,1]  [,2] p.score
##    <int> <fct> <int> <int>   <dbl>
##  1   244 0         0   312   0.285
##  2   449 0         1   399   0.284
##  3   308 0         3   244   0.367
##  4   520 1         1   393   0.286
##  5   225 0         0   132   0.330
##  6   353 1         0   475   0.248
##  7   305 0         2   348   0.317
##  8   426 0         0   389   0.267
##  9   333 0         0   256   0.299
## 10   378 0         1   320   0.304
#hist(p.score)

ggplot(df, aes(x=`p.score`, color=`A`, fill=A)) + 
 geom_histogram(aes(y=..density..), alpha=0.5, 
                position="identity")+
 geom_density(alpha=.2) 

5.2 Step 2: Implementing a matching method

Implementing a matching method, given that measure of closeness

Once a distance measure has been selected, the next step is to use that distance in doing the matching. In this section we provide an overview of the spectrum of matching methods available. The methods primarily vary in terms of the number of individuals that remain after matching and in the relative weights that different individuals receive.

  • Nearest neighbor matching
  • Subclassification, Full Matching and Weighting

5.3 Method 1: Nearest neighbor matching

One of the most common, and easiest to implement and understand, methods is k:1 nearest neighbor matching (Rubin, 1973a). This is generally the most effective method for settings where the goal is to select individuals for follow-up. Nearest neighbor matching nearly always estimates the ATT, as it matches control individuals to the treated group and discards controls who are not selected as matches.

In its simplest form, 1:1 nearest neighbor matching selects for each treated individual i the control individual with the smallest distance from individual i. A common complaint regarding 1:1 matching is that it can discard a large number of observations and thus would apparently lead to reduced power. An additional concern is that, without any restrictions, k:1 matching can lead to some poor matches, if for example, there are no control individuals with propensity scores similar to a given treated individual. One strategy to avoid poor matches is to impose a caliper and only select a match if it is within the caliper. This can lead to difficulties in interpreting effects if many treated individuals do not receive a match, but can help avoid poor matches. Rosenbaum and Rubin (1985a) discuss those trade-offs.

5.3.1 Step 3: Fit & assess the quality of the resulting matched samples

Assessing the quality of the resulting matched samples, and perhaps iterating with Steps (1) and (2) until well-matched samples resul

# analysis 1:  nearest neighbor matching
match.nn  = matchit(A ~ V, data=HERS)
match.nn$match.matrix                 # list matched pairs
##     [,1] 
## 4   "90" 
## 6   "49" 
## 12  "3"  
## 14  "326"
## 16  "283"
## 17  "200"
## 18  "181"
## 20  "261"
## 21  "140"
## 23  "221"
## 24  "282"
## 29  "217"
## 31  "175"
## 35  "154"
## 37  "1"  
## 38  "338"
## 39  "70" 
## 42  "68" 
## 43  "28" 
## 44  "193"
## 48  "239"
## 52  "89" 
## 55  "236"
## 60  "129"
## 62  "225"
## 67  "224"
## 72  "315"
## 74  "172"
## 77  "198"
## 84  "289"
## 91  "137"
## 101 "145"
## 102 "212"
## 103 "293"
## 108 "316"
## 110 "253"
## 111 "25" 
## 117 "97" 
## 118 "88" 
## 120 "264"
## 121 "69" 
## 122 "56" 
## 125 "178"
## 127 "256"
## 130 "266"
## 131 "96" 
## 132 "45" 
## 138 "226"
## 141 "65" 
## 143 "232"
## 146 "32" 
## 148 "128"
## 151 "357"
## 155 "99" 
## 160 "243"
## 165 "284"
## 167 "180"
## 168 "33" 
## 177 "104"
## 183 "233"
## 187 "344"
## 188 "317"
## 190 "309"
## 197 "329"
## 199 "314"
## 206 "22" 
## 219 "295"
## 222 "107"
## 223 "297"
## 227 "144"
## 228 "307"
## 229 "161"
## 238 "241"
## 240 "263"
## 242 "205"
## 245 "189"
## 248 "185"
## 251 "341"
## 254 "218"
## 257 "142"
## 260 "135"
## 265 "170"
## 268 "322"
## 272 "258"
## 273 "250"
## 275 "153"
## 279 "75" 
## 280 "291"
## 281 "353"
## 286 "159"
## 288 "325"
## 292 "85" 
## 303 "7"  
## 305 "41" 
## 308 "184"
## 311 "355"
## 318 "323"
## 320 "186"
## 327 "234"
## 328 "5"  
## 332 "93" 
## 336 "76" 
## 337 "270"
## 339 "312"
## 342 "19" 
## 345 "30" 
## 348 "83" 
## 349 "196"
## 350 "211"
## 352 "64" 
## 354 "351"
m.data.nn   = match.data(match.nn)    # nearest neighbor

summary(match.nn)
## 
## Call:
## matchit(formula = A ~ V, data = HERS)
## 
## Summary of Balance for All Data:
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3086          0.1844     0.9912    0.0585
## V1              0.6847        0.5854          0.0928     1.3128    0.0250
## V2            249.5856      270.5366         -0.1537     1.0865    0.0463
##          eCDF Max
## distance   0.1379
## V1         0.0561
## V2         0.1084
## 
## 
## Summary of Balance for Matched Data:
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3154          0.0133     1.0370    0.0036
## V1              0.6847        0.7117         -0.0253     1.1580    0.0270
## V2            249.5856      253.7838         -0.0308     1.0925    0.0153
##          eCDF Max Std. Pair Dist.
## distance   0.0270          0.0160
## V1         0.0721          0.6482
## V2         0.0631          0.4341
## 
## Percent Balance Improvement:
##          Std. Mean Diff. Var. Ratio eCDF Mean eCDF Max
## distance            92.8     -313.2      93.8     80.4
## V1                  72.8       46.1      -8.3    -28.4
## V2                  80.0       -6.6      66.9     41.8
## 
## Sample Sizes:
##           Control Treated
## All           246     111
## Matched       111     111
## Unmatched     135       0
## Discarded       0       0

5.3.1.1 Distribution of the resulting matched samples

plot(match.nn)

plot(match.nn, type="hist")

plot( summary(match.nn, standardize=T))

5.3.2 Step 4: Analysis of the outcome and estimation of the treatment effect

Analysis of the outcome and estimation of the treatment effect, given the matching done in Step (3).

5.3.2.1 Regression analyses of matched data

# regression analyses of matched data
model.0.nn = lm(Y ~ A , data=m.data.nn)
summary(model.0.nn)
## 
## Call:
## lm(formula = Y ~ A, data = m.data.nn)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -281.79 -126.15  -22.77  102.48  433.21 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   259.27      15.55  16.673   <2e-16 ***
## A              28.52      21.99   1.297    0.196    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 163.8 on 220 degrees of freedom
## Multiple R-squared:  0.007588,   Adjusted R-squared:  0.003077 
## F-statistic: 1.682 on 1 and 220 DF,  p-value: 0.196

5.3.2.2 Increase efficiency by including confounders

# increase efficiency by including confounders
model.1.nn = lm(Y ~ A  + V3 + V4, data=m.data.nn)
summary(model.1.nn)
## 
## Call:
## lm(formula = Y ~ A + V3 + V4, data = m.data.nn)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -252.62  -54.55  -14.74   58.14  342.68 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  4.16429   15.73473   0.265   0.7915    
## A           32.77939   12.84225   2.552   0.0114 *  
## V3           2.41218    6.25141   0.386   0.7000    
## V4           0.99845    0.04841  20.624   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 95.65 on 218 degrees of freedom
## Multiple R-squared:  0.6648, Adjusted R-squared:  0.6602 
## F-statistic: 144.1 on 3 and 218 DF,  p-value: < 2.2e-16

5.4 Method 2: Full matching

A more sophisticated form of subclassification, full matching, selects the number of subclasses automatically (Rosenbaum, 1991; Hansen, 2004; Stuart and Green, 2008). Full matching creates a series of matched sets, where each matched set contains at least one treated individual and at least one control individual (and each matched set may have many from either group). Like subclassification, full matching can estimate either the ATE or the ATT.

Full matching is optimal in terms of minimizing the average of the distances between each treated individual and each control individual within each matched set. Hansen (2004) demonstrates the method in the context of estimating the effect of SAT coaching. In that example the original treated and control groups had propensity score differences of 1.1 standard deviations, but the matched sets from full matching differed by only 0.01 to 0.02 standard deviations. Full matching may thus have appeal for researchers who are reluctant to discard some of the control individuals but who want to obtain optimal balance on the propensity score. To achieve efficiency gains, Hansen (2004) also introduces restricted ratios of the number of treated individuals to the number of control individuals in each

5.4.1 Step 3: Fit & assess the quality of the resulting matched samples

Assessing the quality of the resulting matched samples, and perhaps iterating with Steps (1) and (2) until well-matched samples resul

match.full = matchit(A ~ V , data=HERS, method="full")
m.data.full  = match.data(match.full)   # full matching
match.full$match.matrix                 # list matched pairs
## NULL
summary(match.full)
## 
## Call:
## matchit(formula = A ~ V, data = HERS, method = "full")
## 
## Summary of Balance for All Data:
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3086          0.1844     0.9912    0.0585
## V1              0.6847        0.5854          0.0928     1.3128    0.0250
## V2            249.5856      270.5366         -0.1537     1.0865    0.0463
##          eCDF Max
## distance   0.1379
## V1         0.0561
## V2         0.1084
## 
## 
## Summary of Balance for Matched Data:
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3162         -0.0045     0.9832    0.0053
## V1              0.6847        0.7381         -0.0499     1.1639    0.0275
## V2            249.5856      253.3810         -0.0278     1.0679    0.0161
##          eCDF Max Std. Pair Dist.
## distance   0.0270          0.0240
## V1         0.0861          0.5652
## V2         0.0571          0.3824
## 
## Percent Balance Improvement:
##          Std. Mean Diff. Var. Ratio eCDF Mean eCDF Max
## distance            97.6      -92.6      90.9     80.4
## V1                  46.2       44.2     -10.2    -53.4
## V2                  81.9       20.8      65.3     47.4
## 
## Sample Sizes:
##               Control Treated
## All             246.      111
## Matched (ESS)   159.9     111
## Matched         246.      111
## Unmatched         0.        0
## Discarded         0.        0

5.4.1.1 Distribution of the resulting matched samples

plot(match.full)

plot(match.full, type="hist") 

plot( summary(match.full, standardize=T))

5.4.2 Step 4: Analysis of the outcome and estimation of the treatment effect

Analysis of the outcome and estimation of the treatment effect, given the matching done in Step (3).

5.4.2.1 Regression analyses of matched data

# regression analyses of matched data
model.0.full = lm(Y ~ A , data=m.data.full, weights=weights)
summary(model.0.full)
## 
## Call:
## lm(formula = Y ~ A, data = m.data.full, weights = weights)
## 
## Weighted Residuals:
##     Min      1Q  Median      3Q     Max 
## -375.81 -103.79    0.21   99.08  496.57 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   258.44      10.24  25.227   <2e-16 ***
## A              29.35      18.37   1.598    0.111    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 160.7 on 355 degrees of freedom
## Multiple R-squared:  0.007138,   Adjusted R-squared:  0.004341 
## F-statistic: 2.552 on 1 and 355 DF,  p-value: 0.111

5.4.2.2 Increase efficiency by including confounders

# increase efficiency by including confounders
model.1.full = lm(Y ~ A + V3 + V4, data=m.data.full, weights=weights)
summary(model.1.full)
## 
## Call:
## lm(formula = Y ~ A + V3 + V4, data = m.data.full, weights = weights)
## 
## Weighted Residuals:
##     Min      1Q  Median      3Q     Max 
## -378.68  -49.05   -8.42   43.98  440.87 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  9.51064   11.56380   0.822  0.41138    
## A           32.99557   10.57690   3.120  0.00196 ** 
## V3          -1.97935    4.83069  -0.410  0.68224    
## V4           0.98821    0.03685  26.814  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 92.47 on 353 degrees of freedom
## Multiple R-squared:  0.6731, Adjusted R-squared:  0.6703 
## F-statistic: 242.2 on 3 and 353 DF,  p-value: < 2.2e-16

5.5 Method 3: Subclassification

Subclassification forms groups of individuals who are similar, for example as defined by quintiles of the propensity score distribution. It can estimate either the ATE or the ATT, as discussed further in Section 5. One of the first uses of subclassification was Cochran (1968), which examined subclassification on a single covariate (age) in investigating the link between lung cancer and smoking. Cochran (1968) provides analytic expressions for the bias reduction possible using subclassification on a univariate continuous covariate; using just five subclasses removes at least 90% of the initial bias due to that covariate. Rosenbaum and Rubin (1985b) extended that to show that creating five propensity score subclasses removes at least 90% of the bias in the estimated treatment effect due to all of the covariates that went into the propensity score. Based on those results, the current convention is to use 5–10 subclasses. However, with larger sample sizes more subclasses (e.g., 10–20) may be feasible and appropriate (Lunceford and Davidian, 2004). More work needs to be done to help determine the optimal number of subclasses: enough to get adequate bias reduction but not too many that the within-subclass effect estimates become unstable.

5.5.1 Step 3: Fit & assesses the quality of the resulting matched samples

Assessing the quality of the resulting matched samples, and perhaps iterating with Steps (1) and (2) until well-matched samples resul

match.sub = matchit(A ~ V , data=HERS, method="subclass", subclass=5)
m.data.sub  = match.data(match.sub)
summary(match.sub)        
## 
## Call:
## matchit(formula = A ~ V, data = HERS, method = "subclass", subclass = 5)
## 
## Summary of Balance for All Data:
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3086          0.1844     0.9912    0.0585
## V1              0.6847        0.5854          0.0928     1.3128    0.0250
## V2            249.5856      270.5366         -0.1537     1.0865    0.0463
##          eCDF Max
## distance   0.1379
## V1         0.0561
## V2         0.1084
## 
## Summary of Balance Across Subclasses
##          Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean
## distance        0.3160        0.3179         -0.0475     0.9416    0.0110
## V1              0.6847        0.7095         -0.0232     1.0878    0.0251
## V2            249.5856      244.3795          0.0382     1.0987    0.0192
##          eCDF Max
## distance   0.0413
## V1         0.0601
## V2         0.0544
## 
## Percent Balance Improvement:
##          Std. Mean Diff. Var. Ratio eCDF Mean eCDF Max
## distance            74.3        5.0      81.2     70.0
## V1                  75.0       17.1      -0.5     -7.1
## V2                  75.2       -1.1      58.5     49.8
## 
## Sample Sizes:
##               Control Treated
## All            246.       111
## Matched (ESS)  218.72     111
## Matched        246.       111
## Unmatched        0.         0
## Discarded        0.         0

5.5.1.1 Distribution of the resulting matched samples

plot(match.sub, type="hist")

plot( summary(match.sub, standardize=T))

5.5.2 Step 4: Analysis of the outcome and estimation of the treatment effect

Analysis of the outcome and estimation of the treatment effect, given the matching done in Step (3).

5.5.2.1 Regression analyses of matched data

model.2.sub = lm(Y ~ A + as.factor(subclass), data=m.data.sub)
summary(model.2.sub)
## 
## Call:
## lm(formula = Y ~ A + as.factor(subclass), data = m.data.sub)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -324.07  -87.07  -23.07   68.93  462.45 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            426.07      12.65  33.669  < 2e-16 ***
## A                       37.74      13.66   2.763  0.00603 ** 
## as.factor(subclass)2  -113.70      18.00  -6.317 8.09e-10 ***
## as.factor(subclass)3  -190.57      20.73  -9.193  < 2e-16 ***
## as.factor(subclass)4  -244.52      18.46 -13.243  < 2e-16 ***
## as.factor(subclass)5  -321.24      19.67 -16.335  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 118 on 351 degrees of freedom
## Multiple R-squared:  0.4862, Adjusted R-squared:  0.4789 
## F-statistic: 66.43 on 5 and 351 DF,  p-value: < 2.2e-16

6 Synthesis

drawing

7 Session Info

## R version 3.6.2 (2019-12-12)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS  10.16
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] optmatch_0.9-15  survival_3.2-13  RItools_0.1-18   SparseM_1.81    
##  [5] MatchIt_4.3.3    skimr_2.1.3      kableExtra_1.3.4 knitr_1.37      
##  [9] forcats_0.5.1    stringr_1.4.0    dplyr_1.0.8      purrr_0.3.4     
## [13] readr_2.1.2      tidyr_1.2.0      tibble_3.1.6     ggplot2_3.3.5   
## [17] tidyverse_1.3.1 
## 
## loaded via a namespace (and not attached):
##  [1] svd_0.5           httr_1.4.2        sass_0.4.0        jsonlite_1.7.3   
##  [5] viridisLite_0.4.0 splines_3.6.2     modelr_0.1.8      bslib_0.3.1      
##  [9] assertthat_0.2.1  highr_0.9         cellranger_1.1.0  yaml_2.2.2       
## [13] lattice_0.20-45   pillar_1.7.0      backports_1.4.1   glue_1.6.1       
## [17] digest_0.6.29     rvest_1.0.2       colorspace_2.0-2  survey_4.1-1     
## [21] htmltools_0.5.2   Matrix_1.3-3      pkgconfig_2.0.3   broom_0.7.12     
## [25] haven_2.4.3       bookdown_0.24     xtable_1.8-4      scales_1.1.1     
## [29] webshot_0.5.2     svglite_2.1.0     tzdb_0.2.0        farver_2.1.0     
## [33] generics_0.1.2    ellipsis_0.3.2    withr_2.4.3       repr_1.1.4       
## [37] cli_3.2.0         magrittr_2.0.2    crayon_1.5.0      readxl_1.3.1     
## [41] evaluate_0.14     fs_1.5.2          fansi_1.0.2       xml2_1.3.3       
## [45] tools_3.6.2       mitools_2.4       hms_1.1.1         lifecycle_1.0.1  
## [49] munsell_0.5.0     reprex_2.0.1      compiler_3.6.2    jquerylib_0.1.4  
## [53] systemfonts_1.0.1 rlang_1.0.1       grid_3.6.2        rstudioapi_0.13  
## [57] labeling_0.4.2    base64enc_0.1-3   rmarkdown_2.11    gtable_0.3.0     
## [61] abind_1.4-5       DBI_1.1.2         R6_2.5.1          lubridate_1.8.0  
## [65] fastmap_1.1.0     utf8_1.2.2        stringi_1.7.6     rmdformats_1.0.3 
## [69] Rcpp_1.0.8        vctrs_0.3.8       dbplyr_2.1.1      tidyselect_1.1.1 
## [73] xfun_0.29