# [R-meta] Question on Forest Plot by subgroups

Viechtbauer, Wolfgang (NP) wo||g@ng@v|echtb@uer @end|ng |rom m@@@tr|chtun|ver@|ty@n|
Fri Jun 23 16:21:49 CEST 2023

```I only looked at the highlighted part (where you use addpoly()) and this is also possible (assuming that the coefficients you pull out from resSep are the estimates you are interested in).

Best,
Wolfgang

>-----Original Message-----
>From: Gabriel Cotlier [mailto:gabiklm01 using gmail.com]
>Sent: Friday, 23 June, 2023 16:12
>To: Viechtbauer, Wolfgang (NP)
>Cc: R Special Interest Group for Meta-Analysis
>Subject: Re: [R-meta] Question on Forest Plot by subgroups
>
>Hello all,
>
>Sorry for the many emails but here is the solution that finally works nicely !!
>
>The issue was that I just needed to define the addpoly() function arguments
>properly as in the code below highlighted in yellow.
>With this code I could produce a forest plot combining two different models :
>1. one general for all dataset obtaining its estimate and CI (at line # -1)
>2. one by grouping using 2 moderators obtaining 2 estimates (one per moderator
>which are particular variables of interest of the meta-analys) and their CI.
>
>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 information
>       ilab.xpos=c(-4.6), # position of extra columns of 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)
>)
># 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)
>
>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(coef(resSep)[[2]], sei = resSep\$se[2], row= 16, mlab="" , efac = 0.5,
>col='blue')
>addpoly(coef(resSep)[[1]], sei = resSep\$se[1] ,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(8.5, 1, pos = 4, cex = 0.90, round(coef(resSep)[[1]],3))
>text(8.5, 16, pos = 4, cex = 0.90, round(coef(resSep)[[2]],3))
>
>dev.off()
```