R 为什么匹配的结果取决于数据的顺序(MatchIt包)?

R 为什么匹配的结果取决于数据的顺序(MatchIt包)?,r,matching,R,Matching,使用matchit函数进行完全匹配时,结果会因输入数据帧的顺序而不同。也就是说,如果数据的顺序改变,结果也会改变。这是令人惊讶的,因为在我的理解中,最优完整算法应该只产生一个最佳解 我是遗漏了什么还是这是一个错误 优化算法也存在类似的差异 下面是一个可复制的示例。对于这两个数据集,子类应该是相同的,而不是相同的。 谢谢你的帮助 # create data nr <- c(1:100) x1 <- rnorm(100, mean=50, sd=20) x2 <- c(rep("a

使用matchit函数进行完全匹配时,结果会因输入数据帧的顺序而不同。也就是说,如果数据的顺序改变,结果也会改变。这是令人惊讶的,因为在我的理解中,最优完整算法应该只产生一个最佳解

我是遗漏了什么还是这是一个错误

优化算法也存在类似的差异

下面是一个可复制的示例。对于这两个数据集,子类应该是相同的,而不是相同的。 谢谢你的帮助

# create data
nr <- c(1:100)
x1 <- rnorm(100, mean=50, sd=20)
x2 <- c(rep("a", 20),rep("b", 60), rep("c", 20))
x3 <- rnorm(100, mean=230, sd=2)
outcome <- rnorm(100, mean=500, sd=20)
group <- c(rep(0, 50),rep(1, 50))

df <- data.frame(x1=x1, x2=x2, outcome=outcome, group=group, row.names=nr, nr=nr)
df_neworder <- df[order(outcome),]  # re-order data.frame

# perform matching
model_oldorder <- matchit(group~x1, data=df, method="full", distance ="logit")
model_neworder <- matchit(group~x1, data=df_neworder, method="full", distance ="logit")

# store matching results
matcheddata_oldorder <- match.data(model_oldorder, distance="pscore")
matcheddata_neworder <- match.data(model_neworder, distance="pscore")


# Results based on original data.frame
head(matcheddata_oldorder[order(nr),], 10)
          x1 x2  outcome group nr    pscore weights subclass
1  69.773776  a 489.1769     0  1 0.5409943     1.0       27
2  63.949637  a 529.2733     0  2 0.5283582     1.0       32
3  52.217666  a 526.7928     0  3 0.5028106     0.5       17
4  48.936397  a 492.9255     0  4 0.4956569     1.0        9
5  36.501507  a 512.9301     0  5 0.4685876     1.0       16


# Results based on re-ordered data.frame
head(matcheddata_neworder[order(matcheddata_neworder$nr),], 10)
          x1 x2  outcome group nr    pscore weights subclass
1  69.773776  a 489.1769     0  1 0.5409943     1.0       25
2  63.949637  a 529.2733     0  2 0.5283582     1.0       31
3  52.217666  a 526.7928     0  3 0.5028106     0.5       15
4  48.936397  a 492.9255     0  4 0.4956569     1.0        7
5  36.501507  a 512.9301     0  5 0.4685876     2.0       14
#创建数据

nroptmatch软件包(matchit函数调用该软件包)的开发人员提供了有用的帮助:

我认为我们在这里看到的是宽容争论的结果 那场全场比赛已经结束了。匹配算法需要整数距离, 所以我们必须缩放然后截断浮点距离。暂时 给定一组整数距离,可能有多个匹配 达到最小值,因此解算器可以在这些值中自由选择 非唯一解决方案

进一步开发您的示例:
>库(optmatch)
>nr glm_新订单匹配打开(glm(组~x1,数据=df_新订单),数据=df_新订单)
>fm_旧fm_新平均值(匹配距离(fm_旧值、glm_旧值、平均值))
> ## 0.06216174 
>平均值(sapply(匹配距离(fm_new,glm_neworder),平均值))
>###0.062058平均值(匹配的距离(fm#u old,glm#u older),平均值)-
>平均值(sapply(匹配距离(fm_new,glm_neworder),平均值))
> ## 0.00010373 
我们可以看到它小于默认公差0.001。您始终可以降低公差级别,这可能会导致

需要增加运行时间,以便更接近真实情况 浮动看跌期权最小。我们发现0.001在实践中似乎运行良好, 但这个值没有什么特别之处


optmatch包(matchit函数调用该包)的开发人员提供了有用的帮助:

我认为我们在这里看到的是宽容争论的结果 那场全场比赛已经结束了。匹配算法需要整数距离, 所以我们必须缩放然后截断浮点距离。暂时 给定一组整数距离,可能有多个匹配 达到最小值,因此解算器可以在这些值中自由选择 非唯一解决方案

进一步开发您的示例:
>库(optmatch)
>nr glm_新订单匹配打开(glm(组~x1,数据=df_新订单),数据=df_新订单)
>fm_旧fm_新平均值(匹配距离(fm_旧值、glm_旧值、平均值))
> ## 0.06216174 
>平均值(sapply(匹配距离(fm_new,glm_neworder),平均值))
>###0.062058平均值(匹配的距离(fm#u old,glm#u older),平均值)-
>平均值(sapply(匹配距离(fm_new,glm_neworder),平均值))
> ## 0.00010373 
我们可以看到它小于默认公差0.001。您始终可以降低公差级别,这可能会导致

需要增加运行时间,以便更接近真实情况 浮动看跌期权最小。我们发现0.001在实践中似乎运行良好, 但这个值没有什么特别之处


匹配算法是否依赖于任何随机数?如果是这样,您需要在运行任何代码之前设置种子?我也会这样做,因为您是从
rnorm
生成数据的,这会使问题重复出现。还要尽量保持向量和变量名的差异。如果我理解正确,算法不应该依赖于随机数。但是,在运行代码之前,我重新尝试设置种子,但结果再次不同。匹配算法是否依赖于任何随机数?如果是这样,您需要在运行任何代码之前设置种子?我也会这样做,因为您是从
rnorm
生成数据的,这会使问题重复出现。还要尽量保持向量和变量名的差异。如果我理解正确,算法不应该依赖于随机数。但是,我在运行代码之前重新尝试设置种子,但结果仍然不同。
Developing your example a little more:
> library(optmatch) 
> nr <- c(1:100) x1 <- rnorm(100, mean=50, sd=20)
> outcome <- rnorm(100, mean=500, sd=20) group <- c(rep(0, 50),rep(1, 50)) 
> df_oldorder <- data.frame(x1=x1, outcome=outcome, group=group, row.names=nr, nr=nr) > df_neworder <- df_oldorder[order(outcome),]  # > re-order data.frame 
> glm_oldorder <- match_on(glm(group~x1, > data=df_oldorder), data = df_oldorder) 
> glm_neworder <- > match_on(glm(group~x1, data=df_neworder), data = df_neworder) 
> fm_old <- fullmatch(glm_oldorder, data=df_oldorder) 
> fm_new <- fullmatch(glm_neworder, data=df_neworder)

> mean(sapply(matched.distances(fm_old, glm_oldorder), mean))
> ## 0.06216174 

> mean(sapply(matched.distances(fm_new, glm_neworder), mean))
> ## 0.062058 mean(sapply(matched.distances(fm_old, glm_oldorder), mean)) -  

> mean(sapply(matched.distances(fm_new, glm_neworder), mean))
> ## 0.00010373