kosukeimai / MatchIt

R package MatchIt
205 stars 42 forks source link

1:1 matching (cem, cutpoints=0) but tollerance/distance on one variable #168

Closed buhtz closed 1 year ago

buhtz commented 1 year ago

In the example below I do 1:1 matching (as discussed in #164). The variable bar is numeric and I want to specify a tolerance of 3 to it. That means 10 could also be matched with values between 7 and 13. But the other variable foo should match exact.

I assume I miss the correct term for this and that is why I couldn't find the correct section in the matchit manual. Could you give me a hint please?

library("MatchIt")

set.seed(0)

k = 40
df <- data.frame(
    group = sample(c('X', 'Y'), k, replace = TRUE),
    foo = sample(LETTERS[1:4], k, replace = TRUE),
    bar = sample(10:20, k, replace = TRUE)
)

m.out <- matchit(
    group ~ foo + bar,
    data = df,
    method = "cem",
    k2k = TRUE,
    cutpoints = 0,
)

summary(m.out)

# get data
m.data <- match.data(m.out)

m.data[order(m.data$foo, m.data$bar), ]
ngreifer commented 1 year ago

What you want is a called a "caliper" and is controlled by the caliper and std.caliper options. caliper lets you specify the width of the desired caliper on the variables you want to place it on (in this case, a caliper of 3 on bar), and std.caliper controls whether the caliper is in raw or standardized units (by default, they are standardized).

To request 1:1 matching with a caliper of 3 on bar and exact matching on foo, you would do

matchit(group ~ bar + foo, data = df, method = "nearest", distance = "scaled_euclidean", 
        caliper = c(bar = 3), std.caliper = FALSE, exact = ~foo)
buhtz commented 1 year ago

Thanks a lot for that.