DEV Community

Vamshi E
Vamshi E

Posted on

Propensity Score Matching in R — 2025 Edition

When you can’t run a randomized experiment, Propensity Score Matching (PSM) offers a powerful way to approximate causal inference using observational data. In 2025, with richer tooling, larger datasets, and more attention to bias and fairness, doing PSM well means more than matching — it means careful feature engineering, diagnostics, performance-aware implementation, and transparent communication.

This guide walks through how to do PSM in R properly, from data preparation through matching, evaluation, and reporting—plus what’s changed in the past few years.

Why PSM Still Matters

- Causal inference from non-experimental data. Many real-world scenarios (marketing campaigns, policy interventions) don’t allow random assignment. PSM helps remove or reduce selection bias by balancing treatment and control on observed confounders.
- Interpretability. Unlike some black-box methods, PSM gives you matched sets you can inspect—what observations got dropped, how covariates compare between groups, and how effect estimates change.
- Versatility. You can apply PSM for evaluating interventions, for guiding feature balancing in machine learning, or for confirming effect direction in quasi-experiments.

What’s New (2025) in Propensity Matching Practice

- Larger datasets, more features. Feature sets are richer (demographics, behavioral metrics, digital signals). Handling high-dimensional confounding is now routine.
- Machine learning-augmented bandwidth. Instead of only logistic regression for the propensity model, there’s more use of flexible models (random forests, gradient boosting) to estimate the score, especially when relationships between covariates and treatment aren’t linear.
- Automated diagnostics and fairness checks. Tools that compute standardized mean differences, balance plots, overlap diagnostics, and check underrepresented groups for potential mismatch.
- Caliper, full matching, matching with varying ratios. More matching methods are used thoughtfully: nearest neighbor with calipers, full matching, optimal matching, genetic matching where available.
- Efficiency and scalability. Using packages or methods that support big data (e.g. match within dplyr/data.table pipelines, parallel computation) to scale PSM to tens or hundreds of thousands of records.

Step-by-Step: Propensity Score Matching in R (Modern Workflow)

Here is a detailed, up-to-date workflow with practical R code sketches.

1. Data Preparation & Feature Selection

  • Clean your data: handle missing values, outliers, ensure feature consistency.
  • Decide on covariates to include in the propensity model: variables that relate both to treatment assignment and outcome (confounders). Don’t include post-treatment variables.
  • Consider transforming or scaling continuous variables; encode categorical variables appropriately (factor, dummy variables).
  • Optionally, illuminate or omit variables with very low variance or too many missing values.

library(dplyr)

df <- read.csv("campaign_data.csv")

df_clean <- df %>%
mutate(
Age = as.numeric(Age),
Income = as.numeric(Income),
Response = as.factor(Ad_Campaign_Response),
Bought = as.integer(Bought)
) %>%
# Handle missing
mutate(
Income = if_else(is.na(Income), median(Income, na.rm = TRUE), Income)
)

2. Estimate Propensity Scores

While logistic regression remains widely used, consider more flexible models if appropriate.

Logistic regression approach

ps_model <- glm(Response ~ Age + Income, family = binomial(), data = df_clean)
df_clean <- df_clean %>% mutate(pscore = predict(ps_model, type = "response"))

Alternative: use a gradient boosting machine for propensity

library(caret)
set.seed(123)
gbm_fit <- train(Response ~ Age + Income, data = df_clean, method = "gbm",
trControl = trainControl(method = "cv"),
verbose = FALSE)
df_clean <- df_clean %>% mutate(pscore_gbm = predict(gbm_fit, type = "prob")[, "1"])

3. Pre-Matching Diagnostics

  • Examine distribution of propensity scores in treatment vs control groups (e.g., via histograms or density plots). Check for overlap.
  • Compute balance on covariates: means, variances; compute Standardized Mean Differences (SMDs). Anything above ~0.1 indicates imbalance.
  • Inspect covariates before matching using summary tables or visual tools.

4. Matching Methods

Use one or more matching methods and compare results:

- Nearest-neighbor matching (1:1 or many:1), possibly with caliper.
- Exact matching on important categorical variables if possible.
- Full or optimal matching (matching to minimize overall distance).
- Full matching allows variable ratios and tends to preserve more units.

library(MatchIt)

Nearest neighbor matching

match_nn <- matchit(Response ~ Age + Income, data = df_clean, method = "nearest", caliper = 0.1)

Full matching

match_full <- matchit(Response ~ Age + Income, data = df_clean, method = "full")

matched_data_nn <- match.data(match_nn)
matched_data_full <- match.data(match_full)

5. Post-Matching Diagnostics

  • Recompute balance: SMDs on covariates in matched sample.
  • Visual balance plots or Love plots.
  • Check sample size, fraction matched, units dropped.
  • Assess overlap and common support (ensure areas of propensity score distribution where treatment and control both have observations).

6. Estimate Treatment Effect

Once you have matched data:

  • Use paired tests (if 1:1 matching), or difference-in-means, or regression on matched sample, possibly controlling residual covariates.
  • Use robust standard errors where appropriate.
  • Consider bootstrap to estimate variance if matching induces complication in error estimation.

Example difference in means

y_treat <- matched_data_nn %>% filter(Response == 1) %>% pull(Bought)
y_control <- matched_data_nn %>% filter(Response == 0) %>% pull(Bought)

effect_estimate <- mean(y_treat) - mean(y_control)

Practical Example Workflow

Here’s a minimal end-to-end sketch:

  1. Load data, clean features.
  2. Estimate propensity scores via logistic regression or GBM.
  3. Inspect overlap and balance.
  4. Apply nearest neighbor matching with caliper.
  5. Check post-matching balance, drop units outside common support.
  6. Estimate treatment effect using matched data, with diagnostics.

Considerations & Limitations

While PSM is flexible, it comes with several limitations you need to keep in mind. First, it only accounts for observed confounders—if important variables are omitted, matching cannot correct for unobserved bias. Second, with many covariates or very complex relationships, simple models for propensity scores (like logistic regression) may misrepresent the true score; machine learning models help, but may introduce variance and tuning complexity. Third, matching often discards some observations (especially in exact or caliper matching), which can reduce sample size and statistical power. Fourth, while matched samples can improve balance, they might still suffer from poor overlap or extrapolation outside the region where treatment and control are comparable. Finally, confidence in effect estimates depends heavily on diagnostics: balanced covariates, stable estimates across matching methods, and transparent reporting of what was dropped and why.

Best Practices & Ethical Reporting

  • Always report diagnostics: SMDs before and after matching; proportion of data matched; units dropped.
  • Use multiple matching methods or sensitivity analyses (try several calipers, nearest neighbor vs full matching) to test robustness.
  • Where possible, simulate placebo treatments or use negative control variables to detect whether matching is fooling you.
  • Maintain transparency: clearly define how treatment and control groups are defined, how propensity model is specified, what thresholds were used.
  • Check fairness: ensure matching doesn’t inadvertently amplify disparities, especially for underrepresented groups.

Final Thoughts

Propensity Score Matching remains one of the strongest tools in the observational causal inference toolkit. In 2025, doing it well means going beyond the textbook: richer feature sets, better diagnostics, scalable match algorithms, and strong fairness/ethical guardrails. When done carefully, PSM can bring clarity to questions about what causes what—whether in marketing, healthcare, public policy, or beyond.

This article was originally published on Perceptive Analytics.

In Norwalk, our mission is simple — to enable businesses to unlock value in data. For over 20 years, we’ve partnered with more than 100 clients — from Fortune 500 companies to mid-sized firms — helping them solve complex data analytics challenges. As a leading Power BI Consulting Services in Norwalk and Tableau Consulting Services in Norwalk, we turn raw data into strategic insights that drive better decisions.

Top comments (0)