为何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
相关产品推荐
相关产品推荐

