[R-meta] Question on Forest Plot by subgroups

Gabriel Cotlier g@b|k|m01 @end|ng |rom gm@||@com
Fri Jun 23 16:18:29 CEST 2023


Hello Wolfgang,
Thanks a lot for the explanation and the example code.
Indeed gives me a good idea, I will give it a try to the example code with
my data now.
Have a nice weekend!!
Kind regards,
Gabriel



On Fri, Jun 23, 2023 at 5:13 PM Viechtbauer, Wolfgang (NP) <
wolfgang.viechtbauer using maastrichtuniversity.nl> wrote:

> Dear Gabriel,
>
> I did not look at the details of your code as it is a bit much to digest
> on a Friday afternoon.
>
> However, if you have a model that contains moderators and you want to add
> polygons to a forest plot based on such a model, you need to use predict()
> with 'newmods' set in such a way that you get the desired predicted values.
> The results can then fed into addpoly(). Here is a simpler example to
> illustrate this:
>
> library(metafor)
>
> dat <- escalc(measure="RR", ai=tpos, bi=tneg, ci=cpos, di=cneg,
>               data=dat.bcg, slab=paste0(author, ", ", year))
>
> # standard random-effects model
> res <- rma(yi, vi, data=dat)
> res
>
> # set up the forest plot
> forest(res, header=TRUE, top=2, shade="zebra", ylim=c(-5,15))
>
> # meta-regression model using 'alloc' as a moderator
> res <- rma(yi, vi, mods = ~ 0 + alloc, data=dat)
>
> # obtain the predicted effects for each level of 'alloc'
> pred <- predict(res, newmods=diag(3))
>
> # add these predicted effects as polygons to the plot
> addpoly(pred, rows=-3, mlab=c("Alternate", "Random", "Systematic"))
>
> # add a horizontal line
> abline(h=-2)
>
> Hopefully, this gives you an idea how you can do something analogous in
> your example.
>
> Best,
> Wolfgang
>
> >-----Original Message-----
> >From: Gabriel Cotlier [mailto:gabiklm01 using gmail.com]
> >Sent: Friday, 23 June, 2023 15:15
> >To: Viechtbauer, Wolfgang (NP)
> >Cc: R Special Interest Group for Meta-Analysis
> >Subject: Re: [R-meta] Question on Forest Plot by subgroups
> >
> >Hello all,
> >
> >I think I solve partially the problem since I can plot the forest graph
> with the
> >subgroup size effect in it together with the model size effect of the
> complete
> >dataset however it is missing  to plot the diamond corresponding to the
> size
> >effect of the groups for both moderartor generated groups in resSep using
> >addpoly() funcion that gives the following error:
> >
> >Error in addpoly.rma(resSep, row = 16, mlab = "", efac = 0.5, col =
> "blue") :
> >  Fitted model should not contain moderators.
> >
> >Error in addpoly.rma(resSep, row = 1, mlab = "", efac = 0.5, col =
> "green") :
> >  Fitted model should not contain moderators.
> >
> >Does anyone know how the diamonds polygon for the size effect could be
> plotted ?
> >Thanks a lot.
> >Regards,
> >Gabriel
> >
> >#########################################-- code for graph--
> >######################################
> >png(filename="ForestComputerSimulationPositiveAndNegatives.png",
> >    res=95, width=1300, height=880, type="cairo")
> >
> >mlabfun <- function(text, res) {
> >  list(bquote(paste(.(text),
> >                    " (Q = ", .(formatC(res$QE, digits=2, format="f")),
> >                    ", df = ", .(res$k - res$p),
> >                    ", p ", .(metafor:::.pval(res$QEp, digits=2,
> showeq=TRUE,
> >sep=" ")), "; ",
> >                    I^2, " = ", .(formatC(I_TOT, digits=1, format="f")),
> "%, ",
> >                    paste(sigma^2,sep = "_", "1"), " = ",
> >.(formatC(res$sigma2[1], digits=3, format="f")), " ",
> >                    paste(sigma^2,sep = "_", "2"), " = ",
> >.(formatC(res$sigma2[2], digits=3, format="f")),")")))}
> >
> >
> >mlabfun1 <- function(text, resSep) {
> >  list(bquote(paste(.(text),
> >                    " (Q = ", .(formatC(resSep$QE, digits=2, format="f")),
> >                    ", df = ", .(resSep$k - resSep$p),
> >                    ", p ", .(metafor:::.pval(resSep$QEp, digits=2,
> showeq=TRUE,
> >sep=" ")), "; ",
> >                 #   I^2, " = ", .(formatC(I_TOT, digits=1, format="f")),
> "%, ",
> >                    paste(sigma^2,sep = "_", "1"), " = ",
> >.(formatC(resSep$sigma2[1], digits=3, format="f")), " ",
> >                    paste(sigma^2,sep = "_", "2"), " = ",
> >.(formatC(resSep$sigma2[2], digits=3, format="f")),")")))}
> >
> >forest(res,
> >       top = 2,
> >       # xlim=c(-8, 6),
> >       # alim = c(-3.36077, 5.181815),
> >       alim = c(-2, 6),
> >       # at=log(c(0.05, 0.25, 1, 4)),
> >       # atransf=exp,
> >       # width = 4,
> >       showweights = TRUE,
> >       ilab=cbind(ni),  # content of extra columns of informaiton
> >       ilab.xpos=c(-4.6), # position of extra columns od information
> >       cex=1,
> >       ylim=c(-1, 22.5), # rows in the y-axis from min-row to max-row
> with text.
> >       slab = paste(dat$Authors, dat$Year, sep = ", "),
> >       order=alloc_char,
> >       rows=c(2:13,17:18), # this devide by groups the studeies (3 groups)
> >=ageregar 4 esopacios entre lineas
> >       mlab=mlabfun("RE Model", res),
> >       # mlab="",
> >       # psize= 1 ,
> >       efac = 0.5, # size of the polygon (the diamond)
> >       # header="Author(s) and Year")
> >)
> ># abline(h=res$k+8, lwd=2, col="white")
> >
> >### set font expansion factor (as in forest() above) and use a bold font
> >op <- par(cex=0.75, font=2)
> >
> >### add additional column headings to the plot
> >text(c(-10.8), res$k+6,  c("Author(s) and Year"), cex = 1.4, font = 2)
> >text(c(-4.6), res$k+6,  c("Samples size"), cex = 1.4, font = 2)
> >text(c(8.3),  res$k+6,  c("Weight"),cex = 1.4, font=2)
> >text(c(8.3),  res$k+5.3, c("%"),cex = 1.4, font=2)
> >text(c(10.8),  res$k+6,  c("Fisher's zr [95% CI]"),cex = 1.4, font=2)
> >text(c(res$k+9), c("Computer Simulation Dataset"), cex = 2, font = 2)
> >
> >
> >### switch to bold italic font
> >par(font=4)
> >
> >### add text for the subgroups
> >text(-12.3, c(14,19), pos=4, c("Positive",
> >                               "Negative"), cex = 1.4)
> >
> >### set par back to the original settings
> >par(op)
> >
> >### add summary polygons for the three subgroups
> >addpoly(resSep, row= 16, mlab="" , efac = 0.5, col='blue')
> >addpoly(resSep, row= 1,  mlab="", efac = 0.5, col='green')
> >
> ># text(x=-1, y=-2:80, labels=c(-2:80), col = "red" )
> >
> >text(-12.5, 1, pos = 4, cex = 0.90, bquote(paste("RE Model (Q = ",
> >.(formatC(resSep$QE, digits=2, format="f")),
> >                                                 ", df = ", .(resSep$k -
> >resSep$p),
> >                                                 ", p = ",
> >.(metafor:::.pval(resSep$QEp, digits=2, showeq=TRUE, sep=" ")), "; ",
> >                                                 # I^2, " = ",
> .(formatC(I_NEG,
> >digits=1, format="f")), "%, ",
> >                                                 paste(sigma^2,sep = "_",
> "1"), "
> >= ", .(formatC(resSep$sigma2[1], digits=3, format="f")), " ",
> >                                                 paste(sigma^2,sep = "_",
> "2"), "
> >= ", .(formatC(resSep$sigma2[2], digits=3, format="f"))
> >)))
> >
> >
> >text(-12.5, 16, pos = 4, cex = 0.90, bquote(paste("RE Model (Q = ",
> >.(formatC(resSep$QE, digits=2, format="f")),
> >                                                  ", df = ", .(resSep$k -
> >resSep$p),
> >                                                  ", p = ",
> >.(metafor:::.pval(resSep$QEp, digits=2, showeq=TRUE, sep=" ")), "; ",
> >                                                  # I^2, " = ",
> .(formatC(I_POS,
> >digits=1, format="f")), "%, ",
> >                                                  paste(sigma^2,sep =
> "_", "1"),
> >" = ", .(formatC(resSep$sigma2[1], digits=3, format="f")), " ",
> >                                                  paste(sigma^2,sep =
> "_", "2"),
> >" = ", .(formatC(resSep$sigma2[2], digits=3, format="f"))
> >)))
> >
> >text(10.8, 1, pos = 4, cex = 0.90, round(coef(resSep)[[1]],3))
> >text(10.8, 16, pos = 4, cex = 0.90, round(coef(resSep)[[2]],3))
> >
> >dev.off()
>

	[[alternative HTML version deleted]]



More information about the R-sig-meta-analysis mailing list