Changelog
Source:NEWS.md
Changes in optmatch Version 0.10.6
CRAN release: 20230207
 Adjusted a check to avoid ambiguous failures when using LEMON vs RELAXIV.
 Updated CITATION to use
bibentry()
.  Minor tweaks to address failing tests.
Changes in optmatch Version 0.10.5
CRAN release: 20220815
Minor revision to address a failing test.
Changes in optmatch Version 0.10.4
CRAN release: 20220809
 When including factor variables on the right hand side of the formula passed into
match_on()
, now more simply calculates the contrast to enable more intuitive results. (Thanks Noah Greifer, #220) 
dbind()
will now properly support binding more than 26 unique matrices when renaming is necessary; in fact it supports up to 18,278 uniquely renamed matrices.  A few tweaks in documentation, testing and vignettes to satisfy CRAN requirements and harden against loss of dependencies.
Changes in optmatch Version 0.10.3
CRAN release: 20220516
Interface changes
 The rank Mahalanobis distance being created in
match_on()
using the argumentmethod = "rank_mahalanobis"
was accidentally returning the squared distance rather than the distance. This has been fixed. To recover results using the squared distance, square the results, e.g.:match_on(..., method = "rank_mahalanobis")^2
. (Thanks Noah Greifer #218)  New function
as.list.BlockedInfinitySparseMatrix()
to split a singleBlockedInfinitySparseMatrix
into alist
ofInfinitySparseMatrix
based upon the separate blocks. (Called viaas.list(b)
whenb
is aBlockedInfinitySparseMatrix
.)  New function
dbind()
for binding several distance matrices into a singleBlockedInfinitySparseMatrix
. Valid inputs include any distance convertible into anInfinitySparseMatrix
, orBlockedInfinitySparseMatrix
, orlist
s of these. (#65)
Infrastructure changes
 Manually correcting
License_is_FOSS
andLicense_restricts_use
flags after 0.10.0 transition to an open license. 
optmatch no longer depends on digest, RItools, or survey, or imports from survival. This should harden us against unexpected downtime should any of these packages be removed from CRAN.
 Implemented
optmatch::strata
to be used in place ofsurvival::strata
. Loading survival and maskingstrata
should not cause issues either.  Hashing of distance matrixes is now done internally.
 RItools and survey are now only suggested with appropriate warnings if users attempt to utilize code with them without first installing the packages.
 Implemented
 Modernized some vignettes
(Note: 0.10.1 and 0.10.2 were functionally equivalent releases updated to address an issue with CRAN and the License_is_FOSS
and License_restricts_use
flags.)
Changes in optmatch Version 0.10.0
CRAN release: 20220315
Major changes
 optmatch no longer includes the RELAXIV solver internally. That solver can be still be used by installing the new rrelaxiv package (which will not be hosted on CRAN). When rrelaxiv is not available, optmatch instead uses a mincost flow solver provided by the LEMON project, https://lemon.cs.elte.hu/trac/lemon; bindings to these are provided by the rlemon package. The user interface remains the same, other than a new optional argument for specifying which solver to use. In very limited testing, we’ve seen similar matching results with the new solver.
 The rlemon package offers bindings to four LEMON solvers. See
help(fullmatch)
for a discussion on those, and the new argument tofullmatch()
,solver =
.  To continue using the RELAXIV solver, whether for backcompatibility or as a matter of preference, install the rrelaxiv package, from https://errickson.net/rrelaxiv/. If rrelaxiv is installed, RELAXIV will become the default solver automatically.
Changes in optmatch Version 0.916
 Bug fix: integer overflow issue arising with large problems (#209)
 Minor refinement of support for glms from
survey::svyglm()
(#194)
Changes in optmatch Version 0.915
CRAN release: 20210817
 Small bug fix related to
survey::mad
andsurvey::med
interface
Changes in optmatch Version 0.914
CRAN release: 20210526
 Bug fix:
within=
arguments tomatch_on()
, or functions callingmatch_on()
such aspairmatch()
orfullmatch()
, were sometimes ignored (#181).  Binary operations on sparse matching distances now compare dimnames of the two before proceeding (#190).
 Bug fix: when
fullmatch()
orpairmatch()
found it infeasible to create matches within an exact matching category, under some circumstances all members of that category were being placed into a single category labeled1.NA
, or2.NA
etc. Instead, all members of that category are nowNA
(#203).  Fixed a bug causing
match_on()
,scores()
to misinterpret propensity or other scores fitted withsurvey::svyglm()
(#194). 
boxplot()
gains a method forsvyglm
objects, e.g. propensity score models fitted with case weights viasurvey::svyglm()
(#194).  The meaning of one of
match_on.glm()
’s arguments has changed slightly: to circumvent scale standardization when matching on a propensity score or other index, you should now passstandardization.scale = 1
, notstandardization.scale = NULL
(#194).
Changes in optmatch Version 0.912
CRAN release: 20191011
 Fixed a bug causing
summary.optmatch()
to fail b/c of NAs in the treatment variable (#155).  Fixed bug with using custom distance functions (#180) and updated documentation related to custom distance functions.
 Fixed minor compatibility error in Rdevel for math operations on sparse distance matrices (#179).
Changes in optmatch Version 0.911
CRAN release: 20190712
 Added
exclude
argument tomatch_on()
mirroring theexclude
argument forcaliper()
. 
Optmatch
objects now support anupdate()
function,update.Optmatch()
. (#54) 
Optmatch
objects can be combined via ac()
function,c.Optmatch()
. (#68)  Added support for
labelled
treatment vectors which often arise when importing from Stata or SPSS. (#159)  Introduced more informative error messages in a few situations. (#149, #104)
 Better handling of NA’s in variables involved in matching/calipering/exactMatching. (#147)
 Fixed a bug with incorrect results in
matchfailed()
. (#175)
Changes in optmatch Version 0.910
CRAN release: 20180712
 Minor release to fix warnings during CRAN checks.
Changes in optmatch Version 0.99
CRAN release: 20180514
 Fixed a bug that caused the effective sample size to be rounded too aggresively in
summary.optmatch()
.  Improved several error messages and warnings. (#138, #149, #142)
 Fixed use of
if(vectorOfThings)
usage that will give an error in upcoming R release.
Changes in optmatch Version 0.98
CRAN release: 20180116
 If pairmatch is asked to match within a stratum with fewer eligible controls than
controls
times the number of treatments, it now attempts to match in that stratum by leaving out some of the treatment units. (#116)  The treatment indicator must be either numeric 0/1 (1 for treatment, 0 for control) or logical (TRUE for treatment, FALSE for control).
 Support for any other type of treatment vector (factors, character, other numerical values) has been deprecated. You can easily update treatment vectors using conditional statements, e.g. if you have a character “T” and “C”,
treatment_new = treatment == "T"
.  The treatment indicator can now include NA’s. Any observations with NA treatment status will be excluded from distances matrices and will never match. WARNING: if the
data
argument is excluded fromfullmatch()
orpairmatch()
andnum_NA
> 0 entries in the treatment status vector are NA, then the length of the vector produced byfullmatch()
orpairmatch()
won’t match the length of the treatment status vector, havingnum_NA
fewer observations. Don’t forget to pass adata
argument!  Fixed bug affecting rank Mahalanobis matching in combination with calipers and/or exact matching constraints (#128)
 Addressed an issue affecting certain problems with both exact matching and caliper restrictions, where
min.controls
/mean.controls
/max.controls
directives would have been mistakenly applied to the wrong subclasses, resulting in strange warnings and, potentially, spurious match failures or unintended structural restrictions in some subclasses (#129).  Structural restrictions allowing only manyone matches no longer cause
fullmatch()
to automatically fail. I.e. we’ve restored the behaviour of the software prior to version 0.8. (#132)
Changes in optmatch Version 0.97
CRAN release: 20161229
 Added support for CBPS created objects (#121).
 Improvments to documentation for several functions.
 Several small bugfixes.
Changes in optmatch Version 0.96
CRAN release: 20160503
 New material in vignettes, on general use of the package and on import/export of matching results and material between R and SAS or Stata (Josh Errickson).
 New
summary()
methods forInfinitySparseMatrix
(summary.InfinitySparseMatrix()
),BlockedInfinitySparseMatrix
, (summary.BlockedInfinitySparseMatrix()
) andDenseMatrix
(summary.DenseMatrix()
). I.e., you can callsummary()
on the result of a call tomatch_on()
orcaliper()
. The information this returns may be useful for selecting caliper widths, and for managing computational burdens with large matching problems.  Streamlined combinations of exact and propensity score matching. If you include “+ strata(fac)” on the right hand side of a propensity scoring model formula, then pass the fitted model to
pairmatch()
,fullmatch()
ormatch_on()
, then the factor “fac” will both serve as an independent variable for the propensity model and an exact matching variable (#101). See the examples on the help documentation forfullmatch()
. 
pairmatch()
andfullmatch()
no longer generate “matched.distances” attributes for their results. To get this information, usematched.distances()
.  (Internal) methods for sorting of InfinitySparseMatrix’s
 Deprecated: support passing the results of
fill.NAs()
directly toglm()
or similar. Use the traditional formula anddata
argument version. See help documentation forfill.NAs()
for examples.  Fixed: Rcpp incompatibilities for some OSX users (4bbcaca);
boxplot()
method for fitted propensities ignoring varwidth argument (#113); various minor issues affecting package development and deployment (#110,…).
Changes in optmatch Version 0.95
CRAN release: 20150731
 Documentation adjustments.
 Explicit print method for output from explicit calls to
stratumStructure()
.
Changes in optmatch Version 0.94
 Significant speed up of math operations for sparse distance objects (by Josh Buckner).
 Introducing
contr.match_on()
, a new default contrasts function for making Mahalanobis and Euclidean distances. Previously we used R defaults, which (a) generated different answers for the same factor depending on the ordering of the levels and (b) led to different distances for {0,1}valued numeric variables and two level factors. (#80)  match_on now takes strata as element of formula. Now users can write: match_on(z ~ x1 + x2 + strata(exactMatchVar)) Instead of match_on(z ~ x1 + x2, within = exactMatch(z ~ exactMatchVar))
 Fixed bug giving spurious infeasibility warnings, sample size reductions when using
fullmatch()
with feasible combinations ofmin.controls
,mean.controls
/max.controls
andmax.controls
(#92)  Various small bug fixes and documentation improvements.
Changes in optmatch Version 0.93
CRAN release: 20140813
 Fixed memory issues, potential segfaults in solver code. (Thank you, Peter Solenberger).
 Fixed bug in dropping cases with extraneous NAs when using
fullmatch()
orpairmatch()
to create distance specifications directly.  Fixed bug (#83) in
glm()
method formatch_on()
that caused observations with fixable NAs to be dropped too often.  New function
distUnion()
allows combining arbitrary distance specifications.  New function
antiExactMatch()
provides for matches that may only occur between treated and control units with different values on a factor variable. This is the opposite ofexactMatch()
, which ensures matches occur within factor levels.  Can now infer
data
argument in more cases when using thesummary()
method when the RItools package is present.  Additional warnings and clarifications.
Changes in optmatch Version 0.92
 Fixed issue #74 by properly setting the
omit.fraction
argument when there are unmatched controls.  Improvements to the
minExactMatch()
function.  Added
optmatch_verbose_message
option to provide additional warnings.  Fixed crash when all NULL or NA vectors passed as arguments to
fullmatch()
.  Added argument to
caliper()
function that allows returning values that fit the caliper instead of just indicators of which entries fit the caliper width.  Calipers widths can be given pertreated unit, instead of globally.
 Additional binary operators for sparse matrix representations.
 Added new ranked Mahalanobis method for the formula method of
match_on()
.
Changes in optmatch Version 0.91
CRAN release: 20131101
 Subsetting of
Optmatch
objects now preserves (and subsets) the subproblem attribute.  Performance improvements for match_on applied to glm’s.
 The solver update of version 0.90 had a bug that in some circumstances caused hangups or malloc’s [Issue #70]. We believe this is now fixed – but please notify maintainer if you continue to experience the problem. (If you do, we’ll reward you with an easy workaround.)
Changes in optmatch Version 0.90
CRAN release: 20130810
NEW FEATURES
Solver limits now depend on machine limits, not arbitrary constants defined by the optmatch maintainers. For large problems, users will see a warning, but the solver will attempt to solve.
fullmatch()
andpairmatch()
can now take distance generating arguments directly, instead of having to first callmatch_on()
. See the documentation for these two functions for more details.Infeasibility recovery in
fullmatch()
. When passing a combination of constraints (e.g.max.controls
) that would make the matching infeasible,fullmatch()
will now attempt to find a feasible match that respects those constraints, which will likely result in omitting some controls units.An additional argument to
fullmatch()
,mean.controls
, is an alternative to the previousomit.fraction
. (Only one of the two arguments can be presented.) The match will attempt to average mean.controls number of controls per treatment.Each
Optmatch
object now carries with it the constraints used to generate it (e.g.max.controls
) as well as a hashed version of the distance it matched up, to help with some debugging/error checking but avoiding having to carry the entire distance matrix around.Creating a distance matrix prior to matching is now optional.
fullmatch()
now accepts arguments from whichmatch_on()
would create a distance, and create the match behind the scenes.Performance enhancements for distance calculations.
Several new utility functions, including
subdim()
,optmatch_restrictions()
,optmatch_same_distance()
,num_eligible_matches()
. See their help documentation for additional details.Arithmetic operations between InfinitySparseMatrices and vectors are supported. The operation is carried out as column by vector steps.
scores()
function allows including model predictions (such as propensity scores) in formulas directly (such as combining multiple propensity scores). Thescores()
function is preferred to predict() as it makes several smart choices to avoid dropping observations due to partial missingness and other useful preparations for matching.
BUG FIXES
match_on()
is now a S3 generic function, which solves several bugs using propensity models from other packages.summary()
method was giving overly pessimistic warnings about failures.fixed bug in how
Optmatch
objects were printing.
DEPRECATED AND DEFUNCT

mdist()
is now deprecated, in favor ofmatch_on()
.
Changes in optmatch Version 0.83
CRAN release: 20130516
 Changes to make examples compatible with PDF manual
Changes in optmatch Version 0.82
full()
andpair()
are now aliases tofullmatch()
andpairmatch()
All
match_on()
methods takecaliper
arguments (formerly just the numeric method and derived methods had this argument).boxplot methods for fitted propensity score methods (
glm()
andbigglm()
)fill.NAs()
now takescontrasts.arg
argument to mimicmodel.matrix()
Several bug fixes in examples, documentation
The methods
pscore.dist()
andmahal.dist()
are now deprecated, with useful error messages pointing users to replacements.Significant performance improvements for sparse matching problems.
Functions
umatched()
andmatched()
were backwards. Corrected.
Changes in optmatch Version 0.80
CRAN release: 20121117
NEW FEATURES
More efficient data structure for sparse matching problems, those with relatively few allowed (finite) distances between units. Sparse problems often arise when calipers are employed. The new data structure (
InfinitySparseMatrix
) behaves like a simple matrix, allowingcbind()
,rbind()
, andsubset()
operations, making it easier to work with the olderoptmatch.dlist
data structure.match_on()
: A series of methods to generate matching problems using the new data structure when appropriate, or using a standard matrix when the problem is dense. This function is being deployed along side themdist()
function to provide complete backward compatibility. New development will focus on this function for distance creation, and users are encouraged to use it right away. One difference formdist()
users is thewithin
argument. This argument takes an existing distance specification and limits the new comparisons to only those pairs that have finite distances in thewithin
argument. See thematch_on()
,exactMatch()
, andcaliper()
documentation for more details.exactMatch()
: A new function to create stratified matching problems (in which cross strata matches are forbidden). Users can specify the strata using either a factor vector or a convenient formula interface. The results can be used in callsmatch_on()
to limit distance calculations to only within strata treatmentcontrol pairs.New
data
argument tofullmatch()
andpairmatch()
: This argument will set the order of the match to that of therow.names
,names
, or contents of the passeddata.frame
orvector
. This avoids potential bugs caused when theoptmatch
objects were in a different order than users’ data.Test suite expanded and now uses the testthat library.
fill.NAs()
allows (optionally) filling in all columns (previously, the first column was assumed to be an outcome or treatment indicator and was not filled in).New tools to find minimum feasible constraints: Large matching problems could exceed the upper limit for a matching problem. The functions
minExactmatch()
andmaxCaliper()
find the smallest interaction of potential factors for stratified matchings or the largest (most generous) caliper, respectively, that make the problem small enough to fit under the maximum problem size limit. See the help pages for these functions for more information.
BUG FIXES
 Unmatched units are always NA (instead of being labeled
1.NA
or similar). This avoids some obscure bugs when feeding the results offullmatch()
to other functions.
FOR A DETAILED CHANGELOG, SEE https://github.com/markmfredrickson/optmatch
Changes in optmatch Version 0.71
CRAN release: 20110306
NEW FEATURES
pairmatch()
has a new option,remove.unmatchables
, that may be useful in conjunction with caliper matching. Withremove.unmatchables = TRUE
, prior to matching any units with no counterparts within caliper distance are removed. Pair matching can still fail, if for example for two distinct treatment units only a single control, the same one, is available for matching to them; butremove.unmatchables
eliminates one simple and common reason for pair matching to fail.Applying
summary()
to an optmatch object now creates asummary.optmatch
containing the summary information, in addition to reporting it to the console (via asummary.optmatch()
method forprint()
).mdist.formula()
no longer requires an explicit data argument. I.e., you can get away with a call likemdist(Treat~X1+X2S)
if the variablesTreat
,X1
,X2
andS
are available in the environment you’re working from (or in one of its parent environments). Previously you would have had to domdist(Treat~X1+X2S, data=mydata)
. (The latter formulation is still to be preferred, however, in part because with itmdist()
gets to use data’s row names, whereas otherwise it would have to make up row names.)
Changes in optmatch Version 0.7
NEW FEATURES
 New function
fill.NAs()
replaces missing observations (ie. NA values) with minimally informative values (ie. the mean of observed columns).fill.NAs()
handles functions in formulas intelligently and provides missing indicators for each variable. See the help documentation for more information and examples.
BUG FIXES
mdist.function()
method now properly returns anoptmatch.dlist
object for use insummary.optmatch()
, etc.mdist.function()
maintains label on grouping factor.
Changes in optmatch Version 0.6
NEW FEATURES
There is a new generic function,
mdist()
, for creating matching distances. It accepts: fitted glm’s, which it uses to extract propensity distances; formulas, which it uses to construct squared Mahalanobis distances; and functions, with which a user can construct his or her own type of distance. The function method is more intuitive to work with than the oldermakedist()
function.A new function,
caliper()
, builds on themdist()
structure to provide a convenient way to add calipers to a distance. In contrast to earlier ways of adding calipers,caliper()
has an optional argument specify observations to be excluded from the caliper requirement — this permits one to relax it for just a few observations, for instance.summary.optmatch()
now removes strata in which matching failed (b/c the matching problem was found to be infeasible) before summarizing. It also indicates when such strata are present, and how many observations fall in them.Demo has been updated to reflect changes as of version 0.4, 0.5, 0.6.
BUG FIXES
subsetting of objects of class
Optmatch
now preserves matched.distances attribute.fixed bug in
maxControlsCap()
/minControlsCap()
whereby they behaved unreliably on subclasses within which some subjects had no permissible matches.Removed unnecessary panic in
fullmatch()
when it was given amin.controls
argument with attributes other than names (as when it is created bytapply()
).fixed bug wherein
summary.optmatch()
fails to retrieve balance tests if given a propensity model that had function calls in its formula.Documentation pages for
fullmatch()
,pairmatch()
filled out a bit.
Changes in optmatch Version 0.5
NEW FEATURES:

summary.optmatch()
completely revised. It now reports information about the configuration of the matched sets and about matched distances. In addition, if given a fitted propensity model as a second argument it summarizes covariate balance.