Covariate balance for matching & weighting (cobalt)
@misc{cobalt,
title = {cobalt},
author = {Noah Greifer},
howpublished = {\url{https://ngreifer.github.io/cobalt/}},
note = {Software / documentation}
}Follow the analysis.
Select a node to explore the method
Treatment W + covariates X
Data preparation — shapes the raw inputs into what the estimator expects.
Binary treatment plus the covariates to balance (Lalonde: age, educ, race, re74, re75).
data("lalonde", package = "cobalt")
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
Estimate weights / matches (WeightIt / MatchIt)
Data preparation — shapes the raw inputs into what the estimator expects.
Fit a propensity model; produce IPW weights or matched sets.
library(WeightIt)
w <- weightit(treat ~ age + educ + race + re74 + re75, lalonde, estimand = "ATT")
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
[cobalt] Balance tables & Love plots — bal.tab()
A pre-flight check — run this before trusting any estimate downstream.
bal.tab(): standardized mean differences, adjusted vs unadjusted.
Balance tables & Love plots — bal.tab() — Assess covariate balance before/after matching or weighting: standardized mean differences, KS stats, and the publication-ready Love plot.
bal.tab(w, un = TRUE)
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
love.plot()
Reporting — turn the numbers into a figure or table a reader can act on.
Love plot of |SMD| with the 0.1 balance threshold; show before vs after.
love.plot(w, thresholds = c(m = 0.1))
Before using this step, make its assumptions and its output explicit. A useful peer note explains what you would check, what could go wrong, or what would change your interpretation.
Questions to explore- Which assumption matters most here, and what evidence could challenge it?
- What would you check before passing this output to the next step?
Choose a question to start your comment.
Peer discussion
- Bring your experience, a question, or a different perspective.
Log in to comment on this step.
Inputs & data
A binary treatment and the covariates you'll adjust for (e.g. the Lalonde job-training data).
Show data format & exampleHide example
Format — one row per unit: treatment W ∈ {0,1} and covariates X.
W age educ race re74 re75
1 37 11 black 0 0
0 30 12 white 4100 3800
Figures reproduced from cobalt — Noah Greifer — unofficial community showcase; all credit to the original authors.
From the cobalt vignette (Lalonde). Estimate weights/matches, then check that adjustment actually balanced the covariates. Unofficial summary.
Discuss the workflow (2)
Log in to join the discussion.
A causal estimate from observational data without a Love plot is a vibe, not evidence. cobalt makes the balance check trivial.
100%. I put love.plot() in every appendix now. Reviewers love it.
Works with MatchIt, WeightIt, raw weights… one balance API for everything. Underrated.