如何在 MatchIt() R 中计算 eCDF 均值
How to Calculate eCDF Mean in MatchIt() R
我一直在研究 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
从 vignette("assessing-balance") 中,组间协变量的 eCDF 之间的平均距离是 eCDF 均值。
所以,我一直在尝试手动计算 eCDF Mean。例如年龄协变量。
首先,我分离了 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治疗(治疗=1)和未治疗(治疗=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 均值?谢谢!
问题中的问题似乎来自包MatchIt
计算平均值的方法,它们是加权平均值。
下面的代码与问题的代码具有相同的输出,但我 post 在这里是因为我认为它更惯用。绝对更简单。
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 Max(Kolmogorov-Smirnov 统计数据)。
第 1 步:从处理单元和控制单元获取 eCDF(函数,而非向量)
ecdf1 <- ecdf(lalonde$age[lalonde$treat == 1])
ecdf0 <- ecdf(lalonde$age[lalonde$treat == 0])
这些函数的作用是获取变量值 (age
) 和 return 每个值的累积密度。
第 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
使用的实际代码不太透明,但它 运行 快得多。
我一直在研究 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
从 vignette("assessing-balance") 中,组间协变量的 eCDF 之间的平均距离是 eCDF 均值。 所以,我一直在尝试手动计算 eCDF Mean。例如年龄协变量。
首先,我分离了 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治疗(治疗=1)和未治疗(治疗=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 均值?谢谢!
问题中的问题似乎来自包MatchIt
计算平均值的方法,它们是加权平均值。
下面的代码与问题的代码具有相同的输出,但我 post 在这里是因为我认为它更惯用。绝对更简单。
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 Max(Kolmogorov-Smirnov 统计数据)。
第 1 步:从处理单元和控制单元获取 eCDF(函数,而非向量)
ecdf1 <- ecdf(lalonde$age[lalonde$treat == 1])
ecdf0 <- ecdf(lalonde$age[lalonde$treat == 0])
这些函数的作用是获取变量值 (age
) 和 return 每个值的累积密度。
第 2 步:在 age
我们必须使用唯一值的原因是 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
使用的实际代码不太透明,但它 运行 快得多。