[R-pkg-devel] Inconsistent functionality of c++ code in MatchIt

Noah Greifer no@h@gre||er @end|ng |rom gm@||@com
Thu May 11 20:11:56 CEST 2023


Hello,

I'm the mainter of the package *MatchIt*, which uses *Rcpp* to implement
nearest neighbor matching. One way to customize nearest neighbor
matching is to add a caliper, which is the largest distance two units can
be from each other before they are not allowed to be matched. I've had some
users complain recently that the caliper is not working for them, i.e.,
even after specifying a caliper, units are being matched who are
farther apart then the caliper width. I have been unable to replicate this
problem on my Mac; the caliper always works as intended.

One user noted that even when using the same package version, the
performance varied across two machines: one obeyed the caliper and one
didn't. I thought this might be related to the version of R installed, as
for some users updating R fixed the issue, but for others it didn't. I'm
kind of at a loss.

I have a suspicion that the problem is related to the function abs() in the
C++ functions find_right() and find_left() that I wrote to perform the
matching, which are in nn_match_vec.cpp
<https://github.com/kosukeimai/MatchIt/blob/master/src/nn_matchC_vec.cpp>.
I have had problems with abs() before (seemingly related to a namespace
conflict between std and Rcpp). In this case, abs() is used in the
following way:

if (abs(distance[ii] - distance[k]) > caliper_dist) {
    //if closest is outside caliper, break; none can be found
    break;
 }

Here, distance is a NumericVector, and ii and k are ints. My expectation is
that this would dispatch to std::abs() with a double as its input. It's
possible something is going wrong there. I'm wondering if this has to do
with recent changes to R's C++ engine or compilers.

If you want to run code to test whether the caliper is working correctly on
your machine, you can run the following code:

install.packages("MatchIt")
data("lalonde", package = "MatchIt")
m <- MatchIt::matchit(treat ~ age + educ + race + re74,
                      data = lalonde, caliper = .01)
summary(m)$nn

If the caliper is working correctly, you should see a small matrix that has
the row

Matched            88      88

If not, you would see the row

Matched           185     185

The GitHub issue of people complaining about this is here
<https://github.com/kosukeimai/MatchIt/issues/163> along with their
explanations about versions of *MatchIt* and R. The package code is also
there.

Any thoughts or insights about this would really help! Thank you so much!

Noah

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list