使用 CEM 和 MatchIt R 包的不同结果
Differing results using CEM and MatchIt R packages
我 运行 CEM 中的相同模型和使用 cem 方法的 MatchIt 包,但是,我无法获得相同数量的匹配观察值。为什么会这样?当使用相同的规格时,使用这两个包难道不应该得到相同的结果吗?为简单起见,我使用 lalonde 数据集,只匹配三个变量,并使用预定义的切点来确保它们相同。 MatchIt 包总共产生 429 个匹配项,而 cem 包总共产生 441 个匹配项。
library(tidyverse)
library(cem)
library(MatchIt)
data(lalonde)
lalond2 <- lalonde %>%
select(treat, age, re74, re75, re78)
re74cut <- seq(0, 40000, 5000)
re75cut <- seq(0, max(LL$re75)+1000, by=1000)
agecut <- c(20.5, 25.5, 30.5,35.5,40.5)
my.cutpoints <- list(re75=re75cut, re74=re74cut, age=agecut)
m.out <- matchit(treat ~ age + re74 + re75, data = lalond2,
method = "cem",
cutpoints = my.cutpoints)
c.out <- cem(treatment = "treat",
data = lalond2,
drop = c("treat", "re78"),
cutpoints = my.cutpoints)
m.out
A matchit object
- method: Coarsened exact matching
- number of obs.: 614 (original), 429 (matched)
- target estimand: ATT
- covariates: age, re74, re75
c.out
G0 G1
All 429 185
Matched 277 164
Unmatched 152 21
cem
和 MatchIt
中的 CEM 实现有两个不同之处。首先是 cem
中的错误,其次是可以修复的任意选择。可以从这两个包中获得相同的结果,正如我将在下面演示的那样。
首先,cem
有一个错误(或只是一个不受欢迎的功能),即给定分割点之外的任何单元都将被组合在一起。例如,任何 age
小于 20.5 或大于 40.5 的单元将被放置在同一层中。看看第 142 层,您会发现这正是发生的情况:
> lalond2[c.out$strata == 142, 2:4]
age re74 re75
NSW134 20 16318.62 1484.994
PSID201 46 19171.43 1317.677
PSID204 45 16559.72 1265.758
如果你想防止这种情况发生,你需要定义你的分界点来包含整个数据范围,而不仅仅是内部分界点。一种直接的方法是用 c(-Inf, agecut, Inf)
替换每个分割点向量,例如 agecut
。这将正确地绑定 age
的上层和下层并将这些组分开。 MatchIt
自动执行此操作。
第二个与如何处理切割点边界上的值有关。在cem
时,切点边界上的单位将被放置到下层,在MatchIt
时,它们将被放置到上层。为防止这种情况发生,请选择没有人拥有数据的切点值。这可以通过向每个切割点值添加一个小常数来实现。例如,您可以将 agecut
替换为 agecut + .001
。这样就不会出现歧义,两个包之间的结果会对齐。
因此,总结一下,为了确保两个包产生相同的结果,始终确保所有单位都明确地限制在 cutpoints
向量的值内,这可以通过用 -Inf
和 Inf
,并尝试确保切点始终落在变量值之间而不是变量值之上,这可以通过向所需的切点添加一个小常数来完成,如果您想要边界处的值,则为正如果你想让他们在上层,就在下层,负数。
我 运行 CEM 中的相同模型和使用 cem 方法的 MatchIt 包,但是,我无法获得相同数量的匹配观察值。为什么会这样?当使用相同的规格时,使用这两个包难道不应该得到相同的结果吗?为简单起见,我使用 lalonde 数据集,只匹配三个变量,并使用预定义的切点来确保它们相同。 MatchIt 包总共产生 429 个匹配项,而 cem 包总共产生 441 个匹配项。
library(tidyverse)
library(cem)
library(MatchIt)
data(lalonde)
lalond2 <- lalonde %>%
select(treat, age, re74, re75, re78)
re74cut <- seq(0, 40000, 5000)
re75cut <- seq(0, max(LL$re75)+1000, by=1000)
agecut <- c(20.5, 25.5, 30.5,35.5,40.5)
my.cutpoints <- list(re75=re75cut, re74=re74cut, age=agecut)
m.out <- matchit(treat ~ age + re74 + re75, data = lalond2,
method = "cem",
cutpoints = my.cutpoints)
c.out <- cem(treatment = "treat",
data = lalond2,
drop = c("treat", "re78"),
cutpoints = my.cutpoints)
m.out
A matchit object
- method: Coarsened exact matching
- number of obs.: 614 (original), 429 (matched)
- target estimand: ATT
- covariates: age, re74, re75
c.out
G0 G1
All 429 185
Matched 277 164
Unmatched 152 21
cem
和 MatchIt
中的 CEM 实现有两个不同之处。首先是 cem
中的错误,其次是可以修复的任意选择。可以从这两个包中获得相同的结果,正如我将在下面演示的那样。
首先,cem
有一个错误(或只是一个不受欢迎的功能),即给定分割点之外的任何单元都将被组合在一起。例如,任何 age
小于 20.5 或大于 40.5 的单元将被放置在同一层中。看看第 142 层,您会发现这正是发生的情况:
> lalond2[c.out$strata == 142, 2:4]
age re74 re75
NSW134 20 16318.62 1484.994
PSID201 46 19171.43 1317.677
PSID204 45 16559.72 1265.758
如果你想防止这种情况发生,你需要定义你的分界点来包含整个数据范围,而不仅仅是内部分界点。一种直接的方法是用 c(-Inf, agecut, Inf)
替换每个分割点向量,例如 agecut
。这将正确地绑定 age
的上层和下层并将这些组分开。 MatchIt
自动执行此操作。
第二个与如何处理切割点边界上的值有关。在cem
时,切点边界上的单位将被放置到下层,在MatchIt
时,它们将被放置到上层。为防止这种情况发生,请选择没有人拥有数据的切点值。这可以通过向每个切割点值添加一个小常数来实现。例如,您可以将 agecut
替换为 agecut + .001
。这样就不会出现歧义,两个包之间的结果会对齐。
因此,总结一下,为了确保两个包产生相同的结果,始终确保所有单位都明确地限制在 cutpoints
向量的值内,这可以通过用 -Inf
和 Inf
,并尝试确保切点始终落在变量值之间而不是变量值之上,这可以通过向所需的切点添加一个小常数来完成,如果您想要边界处的值,则为正如果你想让他们在上层,就在下层,负数。