Love.plot - display balance for a second set of weights

160 views Asked by At

I have the following data:

library(MatchIt)
library(cobalt)

data("lalonde")

and created weights:

formula <- treat ~ age + educ + married + nodegree

# Calculate PS
propensity_model <- matchit(formula, data = lalonde, method = NULL, distance = 'glm', link = 'logit')

# Store PS
propensity_score <- propensity_model$distance

# Calculate IPW
ipw <- ifelse(lalonde$treat == 1, 1 / propensity_score, 1 / (1 - propensity_score))

# Calculate MW
mw <- ifelse(lalonde$treat == 1, min(propensity_score, 1 - propensity_score) / propensity_score, min(propensity_score, 1 - propensity_score) / (1 - propensity_score))

# Store weights 
weighted_data <- lalonde
weighted_data$mw <- mw
weighted_data$ipw <- ipw

Now I want to create a love.plot to assess balance of unadjusted, ipw and mw as follows:

# Store weights
mw_weights <- weighted_data$mw
ipw_weights <- weighted_data$ipw

# Create the love.plot
love.plot(treat ~ age + educ + married + nodegree,
          data = weighted_data, estimand = "ATE",
          binary = "std",
          stats = c("mean.diffs"),
          weights = list(w1 = mw_weights, 
                         w2 = ipw_weights),
          var.order = "unadjusted",
          abs = TRUE,
          line = FALSE, 
          thresholds = c(m = .1),
          #var.names = new.names,
          colors = c("red", "blue", "darkgreen"),
          shapes = c("triangle filled", "circle filled", "square filled"),
          sample.names = c("Unweighted", "MW", "IPW"),
          limits = list(m = c(0, 1.0)),
          wrap = 20,
          position = "top")

The result shows just unadjusted and ipw and I do not know why mw is missing

Thanks in advance

1

There are 1 answers

2
Noah On BEST ANSWER

This is because you made a mistake in calculating the matching weights. The correct code is

mw <- ifelse(lalonde$treat == 1,
             pmin(propensity_score, 1 - propensity_score) / propensity_score,
             pmin(propensity_score, 1 - propensity_score) / (1 - propensity_score))

You have to use pmin() instead of min() to return a vector; min() returns a single value, so it finds the smallest single value of c(propensity_score, 1 - propensity_score) and applies that to everyone. When using pmin(), the matching weights are calculated correctly and both sets of SMDs appear in the plot.

Note that you can use WeightIt to compute the weights directly, either by using weightit() to estimate weights or get_w_from_ps() to compute weights from supplied propensity scores.