ngreifer / cobalt

Covariate Balance Tables and Plots - An R package for assessing covariate balance
https://ngreifer.github.io/cobalt/
73 stars 11 forks source link

bal.tab()$Max.Imbalance.Variances$V.Ratio.Adj contains the value with maximal absolute value #22

Closed ruzankin closed 5 years ago

ruzankin commented 5 years ago

bal.tab()$Max.Imbalance.Variances$V.Ratio.Adj contains the value with maximal absolute value. So it can be <2 and >0.5 when there are variance ratios <0.5.

The same issue is with summary output. The variable with maximal absolute variance ratio is printed, so it can be balanced even when there are unbalanced variables with respect to variance ratio.

I would also suggest to introduce a simple function like feasible.matching(b), where b=bal.tab(...), which would check whether all variables are balanced. It would be helpful, e.g., for finding feasible calipers for matching.

ngreifer commented 5 years ago

Thank you! Fixed this with 5eac138.

I'm not exactly sure what you mean by "feasible". Does this function just check whether the Max.Imbalance value is balanced? Is your idea to try successively smaller calipers until some level of balance is found?

ruzankin commented 5 years ago

Thank you for your reply! I would like to have a function which checks whether all absolute standardized mean differences are less than m.threshold and all variance ratios are less than v.threshold (the corresponding bal.tab() arguments).

Sometimes one has just to find calipers which yield feasible matchings. If there are plenty of them then one can choose a caliper which corresponds to a best balance on some covariate (that is what I am doing now, though it is not the best way for that).

ngreifer commented 5 years ago

I've added some new functions to cobalt that might be what you want. Among others, I have the function col_w_smd and col_w_vr, which compute standardized mean differences and variance ratios, respectively, for a matrix of covariates and optional weights. They are designed to run pretty quickly, much faster than run bal.tab each time you want to compute a balance statistic.

To choose a caliper using the Matching package, for example, you might run the following:

caliper.grid <- seq(.01, .31, length = 50)
chosen.caliper <- NA_real_
for (i in caliper.grid) {
    M <- Match(Tr = treat, X = prop.score, caliper = i)
    w <- get.w(M)
    smds <- col_w_smd(covs, treat, weights = w, abs = TRUE, 
                      s.d.denom = "treated")
    vrs <- col_w_vr(covs, treat, weights = w, abs = TRUE)
    if (all(smds < .1) && all(vrs < 2)) chosen.caliper <- i
}

The version with these functions will be on CRAN soon and is already on GitHub.