Generalized Propensity Score Estimation and Matching for Multiple Groups
Overview
Implements the Vector Matching algorithm to match multiple treatment groups based on previously estimated generalized propensity scores. The package includes tools for visualizing initial confounder imbalances, estimating treatment assignment probabilities using various methods, defining the common support region, performing matching across multiple groups, and evaluating matching quality. For more details, see Lopez and Gutman (2017) doi:10.1214/17-STS612.
Major changes
balqual()gained two newtypevalues,"desc_full"and"desc_reduced", which report standard descriptive statistics for every balancing variable, separately for each treatment level and for the unmatched and matched dataset. This makes it possible to compare the covariate distributions between both datasets, in addition to the pairwise balance metrics. The tables follow the layout of the balance tables, with the statistics as rows and the two matching stages as theBeforeandAftercolumns. Numeric covariates are summarized byN, mean, standard deviation, minimum, first quartile, median, third quartile, maximum, skewness and excess kurtosis for"desc_full", or byN, minimum, mean, median and maximum for"desc_reduced". Categorical covariates are instead cross-tabulated, with the count and the percentage of every level within each treatment level, computed separately for each matching stage and printed as a singleN (%)cell in a separate table. The two values are mutually exclusive, and both are opt-in, so the default output is unchanged.
Show all changes in 1.4.0Hide the rest of the changes in 1.4.0
match_gps()now works with anyreferencewhenmethod = "nnm". The columns kept for matching were selected with a logical mask built on the fullcsmatrix, but the mask was applied after thetreatmentcolumn had already been dropped, so every position shifted by one. The gps column of the reference was therefore only retained when the reference happened to be the first gps column of thecsmatrix; any other reference failed withundefined columns selected. When it did not fail, the shifted mask kept the neighbouring gps column as well, so [Matching::Matchby()] silently matched on two covariates instead of one and returned a different set of matches. Both branches now index the gps column of the first group of the current combination by name, which also fixes the same error for a user-suppliedcomboswhosegroup1differs fromreference.match_gps()now actually honours themax_controlsargument formethod = "fullopt". It was passed to [optmatch::fullmatch()] under a name that function does not accept and carried the value ofcaliper, so it was silently discarded and had no effect on the matching. Calls that setmax_controlsto a non-default value will now produce different (correct) results.csregion()now stops with an informative message when the common support region turns out to be empty, or when a treatment group loses all of its observations. Previously such a call failed withnon-numeric argument to binary operator, which came from the fallback warning of the internal refitting step rather than from the empty region itself, and gave no hint about the actual cause. Withrefit = FALSEthe same situation returned a zero-rowcsrobject silently, and the problem only surfaced later inmatch_gps(). Emptying a group is now reported as well, since dropping it would silently change the estimand. The new messages name the groups involved and suggest a larger sample, fewer treatment groups, a differentbordersvalue or a different model specification inestimate_gps().
Minor changes and bug fixes
match_gps()no longer warns when a method-specific tuning parameter is left at its default. Previously, a call such asmatch_gps(csr, method = "fullopt")emitted a warning for every unset parameter (order,min_controls,max_controls), which made an ordinary default call look like it had gone wrong. Defaults are now filled in silently. Arguments that do not apply to the selectedmethodare still reported, but only when they were explicitly supplied by the user.- The descriptive metrics of
balqual()describe the covariates as they are given in theformula, while the balance metrics are computed on the model matrix. A factor is therefore described once by its levels rather than once per dummy-coded column, and interaction terms are covered by the balance metrics only. - The
statisticargument ofbalqual()is not used by the descriptive metrics, and a warning is now issued when it is supplied together withtype = "desc_full"ortype = "desc_reduced"alone. - Fixed a bug in
balqual(), where the values of thecutoffsargument were matched to the metrics by position across all three balance metrics rather than by name. Passing a subset of the metrics, e.g.type = c("smd", "var_ratio"), raised a recycling warning and could evaluate a metric against the cutoff of another one. print.quality()now returns its argument invisibly, as documented forprint()methods, instead of returning it visibly. The visible return value made the quality tables be printed twice whenever the result ofprint()was itself auto-printed, e.g. insidecapture.output()or a knitted document.- Fixed the fallback warning of
csregion(), which was emitted when refitting the GPS model on the CSR-restricted data fails. Its message was split into three fragments thatstrwrap()received as thewidthandindentarguments instead of as text, so the warning aborted instead of being shown. optimize_gps()no longer aborts with$ operator is invalid for atomic vectorswhen the GPS estimation fails for the first combination of the search space. Failed combinations are passed through as the message of the underlying error, but the treatment levels were read from the first result unconditionally, so a single failure at the head of the estimation space brought down the whole sweep. The first result that actually holds a GPS matrix is now used instead. If every combination fails, the function stops with a message that reports how many were tried and the reason given by the first failure.
Documentation
- The package documentation is now also available as a
pkgdownwebsite at <https://polymerase3.github.io/vecmatch/>. The site collects the reference pages of all exported functions, grouped by the five steps of thevecmatchworkflow, together with the vignettes and this changelog, and is rebuilt automatically by a GitHub Actions workflow on every push tomain.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-04
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-06-09
- ERROR12 OK, 1 ERROR2026-06-08
- NOTE12 OK, 1 NOTE2026-06-07
Show 3 earlier changesHide 3 earlier changes
- OK13 OK2026-05-12
- WARNING12 OK, 1 WARNING2026-05-11
- OK14 OK2026-03-10
Documentation
- Help pages
- 15 (3 internal)includes a package overview page
- Examples that run
- 73%8 run in a plain check (1 of them under a condition) · 3 only when donttest examples are enabled (R CMD check --as-cran)
- Exported functions with examples
- 85%
- Documented parameters
- 99%
- Return-value docs
- 100%
- Help pages citing references
- 13%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- 99
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
13 development-tooling and community-health practices detected across 8 families in the upstream repository
Checks run against github.com/polymerase3/vecmatch on 2026-10-22.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-09-08 · The repository has a site deploy workflow
pkgdown site last built 2026-09-08
Show all practicesHide 4 practices
This repository shows signs of AI coding tools.
- Claude Codefirst seen on or before 2026-09-08Commits: at least 2 crediting it in the message
Dependencies
Code & Tests
Datasets
People & History
Package metadata
- First published
- 2025-03-07
- Total releases
- 6 / 1 yrs
- License
- GPL (>= 3) OSI
- Minimum R
- ≥ 3.5
- Bundled data
- 19 KB / 1 file
- Download size
- 889 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("vecmatch")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-25, which the citation names so these numbers can be found later. More on citing and the projects behind them.