在遵循 Wolfgang 在标记答案中非常有用的说明的过程中,我创建了一些代码来使用示例数据集执行此操作。发帖以防对其他人有帮助:
更新:根据 Wolfgang 在下面的评论,我删除了 CI 的代码,并将其替换为计算 BLUP 的 SE 的代码。
#load packages and example data
library(metafor)
library(plyr)
library(ggplot2)
dat<-dat.konstantopoulos2011
dat
#make a model - note I have nested random effects
#(no idea if it actually makes sense with this example dataset!)
mod<-rma.mv(yi,vi,mods=~year,random=~1|district/school,data=dat)
#predict from the model (without exponentiating) and attach to original data
preds<-predict.rma(mod,addx=TRUE)
dat$pred<-preds$pred
dat$ci.ub<-preds$ci.ub
dat$ci.lb<-preds$ci.lb
dat$fe_se<-preds$se
dat$dist.sch<-interaction(dat$district,dat$school) #create a label for each district/school
#get the district random effects and label them
dist_re<-data.frame(ranef(mod)$district)
dist_re$district<-rownames(dist_re)
#get the school random effects and label them
sch_re<-data.frame(ranef(mod)$`district/school`)
sch_re$dist.sch<-rownames(sch_re)
sch_re$dist.sch<-gsub("/",".",sch_re$dist.sch)
colnames(sch_re)<-c("intrcpt2","se2","pi.lb2","pi.ub2","dist.sch") #to avoid duplicate colnames later
#join the district and school random effects to the data by labels
plotdat<-join(dat,dist_re,by="district")
plotdat2<-join(plotdat,sch_re,by="dist.sch")
#create the blups and intervals by adding the fixed effect estimates and random effect predictions,
#and exponentiating:
plotdat2$blup<-exp(plotdat2$pred+plotdat2$intrcpt+plotdat2$intrcpt2)
plotdat2$blup.se<-sqrt((plotdat2$fe_se^2)+(plotdat2$se^2)+(plotdat2$se2^2))
#forest plot of BLUPs and their SEs just to check they make sense:
ggplot(plotdat2, aes(y=dist.sch, x=blup, xmin=blup-blup.se, xmax=blup+blup.se))+
geom_point()+
geom_errorbarh(height=.2)+
ylab('District and school')+
geom_vline(xintercept=1,linetype='dashed')+
xlim(0,5)+
theme_bw()