如何在 MatchIt() R 中计算 eCDF 均值

Posted

技术标签:

【中文标题】如何在 MatchIt() R 中计算 eCDF 均值【英文标题】:How to Calculate eCDF Mean in MatchIt() R 【发布时间】:2021-12-20 01:02:38 【问题描述】:

我一直在探索 R 中的 MatchIt() 包,并且想知道如何计算这个包中的 eCDF 平均值。我使用了这个包中的数据 lalonde,并运行了 matchit 包

library("MatchIt")
data("lalonde")
m.out1 <- matchit(treat ~ age + educ + race + married + 
                   nodegree + re74 + re75, data = lalonde,
                 method = "nearest", distance = "glm")

而matchit的总结输出是

Call:
matchit(formula = treat ~ age + educ + race + married + nodegree + 
    re74 + re75, data = lalonde, method = "nearest", distance = "glm")

Summary of Balance for All Data:
           Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Mean eCDF Max
distance          0.5774        0.1822          1.7941     0.9211    0.3774   0.6444
age              25.8162       28.0303         -0.3094     0.4400    0.0813   0.1577
educ             10.3459       10.2354          0.0550     0.4959    0.0347   0.1114
raceblack         0.8432        0.2028          1.7615          .    0.6404   0.6404
racehispan        0.0595        0.1422         -0.3498          .    0.0827   0.0827
racewhite         0.0973        0.6550         -1.8819          .    0.5577   0.5577
married           0.1892        0.5128         -0.8263          .    0.3236   0.3236
nodegree          0.7081        0.5967          0.2450          .    0.1114   0.1114
re74           2095.5737     5619.2365         -0.7211     0.5181    0.2248   0.4470
re75           1532.0553     2466.4844         -0.2903     0.9563    0.1342   0.2876

从小插图(“评估平衡”),跨组协变量的 eCDF 之间的平均距离是 eCDF 均值。 所以,我一直在尝试手动计算 eCDF 平均值。例如年龄协变量。

首先,我将 2 个数据分开,“people1”用于处理数据,“people2”用于未处理数据。然后我为年龄处理 (A) 和年龄未处理 (B) 创建 eCDF

#AGE
people1$age
people=na.omit(people1$age)
age1=ecdf(as.numeric(people))
people2$age
people2=na.omit(people2$age)
age2=ecdf(as.numeric(people2))

as.list(environment(age1))
A=as.data.frame(cbind(as.list(environment(age1))$x, as.list(environment(age1))$y));A
as.list(environment(age2))
B=as.data.frame(cbind(as.list(environment(age2))$x, as.list(environment(age2))$y));B

下面的 C 矩阵是已处理 (A) 和未处理 (B) 的 eCDF。

C=merge(A,B,by="V1",all=TRUE);C
C=na.omit(C) #for delete the row with NA value 
D=abs(C$V2.x-C$V2.y);summary(D)

而 D 是 eCDF 处理 (treat=1) 和未处理 (treat=0) 之间的差异,但均值的结果是:

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
0.01850 0.06193 0.08809 0.09113 0.11888 0.15773

正如您所见,最大差异 eCDF 与 MatchIt() 的输出相同,但差异 eCDF 的均值不一样。有人可以解决这个问题吗?或者知道如何计算 eCDF 均值?谢谢!

【问题讨论】:

你能发布你用来创建data.framesAB的代码吗?因为代码不可重现。 @RuiBarradas 当然,我已经发布了! 【参考方案1】:

这是我见过的最复杂的代码。我将简化事情并向您展示如何计算统计数据。也就是说,该统计数据尚未得到很好的研究,主要是出于历史原因而成为产出的一部分。请改用 eCDF Max(Kolmogorov-Smirnov 统计量)。

第 1 步:从处理单元和控制单元获取 eCDF(它们是函数,而不是向量)

ecdf1 <- ecdf(lalonde$age[lalonde$treat == 1])
ecdf0 <- ecdf(lalonde$age[lalonde$treat == 0])

这些函数的作用是获取变量 (age) 的值并返回每个值的累积密度。

第 2 步:在 age 的每个 unique 值处评估 eCDF

我们必须使用唯一值的原因是 eCDF 已经通过在函数中创建一个步骤来解释重复值。

cum.dens1 <- ecdf1(unique(lalonde$age))
cum.dens0 <- ecdf0(unique(lalonde$age))

第 3 步:计算绝对差的平均值和最大值

ecdf.diffs <- abs(cum.dens1 - cum.dens0)
mean(ecdf.diffs)
# [1] 0.08133907
max(ecdf.diffs)
# [1] 0.157727

我们可以看到我们得到了正确的答案。

MatchIt 使用的实际代码透明度稍差,但运行速度更快。

【讨论】:

【参考方案2】:

问题中的问题来自似乎是包MatchIt 计算平均值的方式,它们是加权平均值。

下面的代码与问题的代码具有相同的输出,但我将其发布在这里,因为我认为它更惯用。它肯定更简单。

library("MatchIt")
data("lalonde")

m.out1 <- matchit(treat ~ age + educ + race + married +
                    nodegree + re74 + re75, data = lalonde,
                  method = "nearest", distance = "glm")
summary(m.out1)

sp_lalonde <- split(lalonde, lalonde$treat)
tmp <- lapply(sp_lalonde, \(x)
  e <- ecdf(x$age)
  out <- as.list(environment(e))[c("x", "y")]
  as.data.frame(out)
)
C <- Reduce(function(x, y) merge(x, y, by = "x", all = TRUE), tmp) |> na.omit()
D <- abs(C[[2]] - C[[3]])

summary(D)
#   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#0.01850 0.06193 0.08809 0.09113 0.11888 0.15773 
mean(apply(C[-1], 1, dist))
#[1] 0.09112509

【讨论】:

谢谢!它看起来更简单。但是,我还没有想出如何手动计算 eCDF 平均值。因为 MatchIt 中的年龄 eCDF 平均值是 0.0813,但根据我们的计算,它是 0.09112509 .. @JasmineHelen 答案在函数代码中,getAnywhere("summary.matchit") 显示它调用qoi 调用wm(加权平均值)。但我无法让它工作并产生summary(m.out1)的输出。

以上是关于如何在 MatchIt() R 中计算 eCDF 均值的主要内容,如果未能解决你的问题,请参考以下文章

“类型”在带有 ecdf 对象的 R 绘图函数中不起作用

R:在数组上应用 ecdf 函数

R语言ggplot2可视化使用stat_ecdf函数可视化一个分布的ECDF经验累积概率分布函数图(Simple ECDF Plot with ggplot2)

如何绘制经验 cdf (ecdf)

vim matchit 自定义配对关键字之间的跳转

Vim系列 - matchit.vim