You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何MatchIt对象绘图与普通对象不同?如何合并其多图到单图?

关于MatchIt多模型诊断图合并的问题

我使用MatchIt开展多组匹配分析,为提升编码效率,通过map循环处理不同协变量集等模型输入,得到一组matchit对象列表,用于提取分析结果与诊断输出。我希望将各模型的诊断图合并为单个图形。

处理普通对象(如iris数据集的直方图)时,以下代码可正常生成包含两个直方图的单个图形:

library(tidyverse) 

plots <- iris %>% select(contains("Sepal")) %>% map(hist)
opar <- par(no.readonly = TRUE)
par(mfrow=c(2,1))
plots %>% map(plot)

但将相同方法应用于matchit对象时,如下代码仅能得到一个挤在图形区域顶部的图,其余图形无法显示:

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

formula1=treat ~ age + educ + race + married + 
  nodegree + re74 + re75
formula2=treat ~ age + educ + race + married + 
  nodegree + re74 + re75
formulas=list(formula1,formula2)

results <- formulas %>% map(~matchit(formula=.x, data=lalonde, method=NULL, distance="glm"))

opar <- par(no.readonly = TRUE)

# set 2 x 1 layout
par(mfrow = c(2,1))
results %>% map(summary) %>% map(plot)
par(opar)

请问为何MatchIt对象与普通对象的绘图结果不同?如何将matchit对象的多个诊断图合并到单个图形中?


为什么MatchIt对象的绘图结果不同?

问题出在plot.summary.matchit()函数(即对summary.matchit对象调用plot()时的方法)的行为上:

  • 普通绘图函数(如hist())会遵循当前的图形参数(比如你设置的mfrow),在指定的子图区域绘图。
  • 但plot.summary.matchit()会主动重置图形布局参数,它默认会生成3张诊断图,并自动设置mfrow=c(2,2)来排列这些图。这会覆盖你之前设置的mfrow=c(2,1),导致第一个模型的诊断图占用整个绘图设备,后续模型的图只能挤在第一个模型绘图后剩下的区域(也就是顶部一小块)。

如何合并多个MatchIt诊断图?

有两种可行的方案,根据你的需求选择:

方案1:逐个绘制单个诊断图,手动控制布局

如果你想为每个模型只展示某一类诊断图(比如仅标准化均值差的箱线图),可以通过plot()的which参数指定绘图类型,同时保留自定义的布局:

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

formula1 <- treat ~ age + educ + race + married + nodegree + re74 + re75
formula2 <- treat ~ age + educ + race + married + nodegree + re74 + re75
formulas <- list(formula1, formula2)

results <- formulas %>% map(~matchit(formula=.x, data=lalonde, method=NULL, distance="glm"))
summaries <- results %>% map(summary)

opar <- par(no.readonly = TRUE)
# 设置2行1列的布局
par(mfrow = c(2,1))
# 为每个summary对象绘制标准化均值差的箱线图(which=1)
summaries %>% map(~plot(.x, which=1, main="标准化均值差对比"))
par(opar)

which参数的可选值:

  • 1:标准化均值差的箱线图
  • 2:倾向得分的密度对比图
  • 3:倾向得分的QQ图

方案2:捕获每个模型的完整诊断图,再合并

如果你想保留每个模型的3张诊断图,将所有图合并到一个大图形中,可以用recordPlot()捕获每个模型的绘图,再用layout()或基础绘图参数排列:

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

formula1 <- treat ~ age + educ + race + married + nodegree + re74 + re75
formula2 <- treat ~ age + educ + race + married + nodegree + re74 + re75
formulas <- list(formula1, formula2)

results <- formulas %>% map(~matchit(formula=.x, data=lalonde, method=NULL, distance="glm"))
summaries <- results %>% map(summary)

# 捕获每个模型的三张诊断图
plot_list <- map(summaries, function(s) {
  plot(s)
  # 捕获当前设备上的所有图形
  lapply(1:3, function(i) {
    p <- recordPlot()
    dev.off()
    p
  })
}) %>% flatten()

# 设置2行3列的布局(每个模型占一行,包含3张图)
opar <- par(no.readonly = TRUE)
par(mfrow = c(2,3))
# 逐个绘制捕获的图形
walk(plot_list, replayPlot)
par(opar)

内容的提问来源于stack exchange,提问作者PaulB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 12:45:34