Background
These R code chunks are related to the following research article which has been published recently. The article can be found via the following link: manuscript link. As the article is sufficiently detailed about the objective and results of the study, this will only serve as a tutorial to perform the analysis and draw the graphs included in the article. Authors believe in reproducible research and this is their way of contributing to the current knowledge. If this code helps you in any way we kindly ask you to cite the aforementioned article (that’s the best way of saying thanks). This tutorial will be focused on the realization of the forest plots (including subgroup analysis).
Prerequisites
We first load the corresponding data we will be using for the analysis, then we load required packages.
BWGF <- read.csv("D:/Chris/ETUDES1/PhD thesis/R files/DATABASE (excel)/glutamine/excels/csvs/BWGF.csv")
GPX <- read.csv("D:/Chris/ETUDES1/PhD thesis/R files/DATABASE (excel)/glutamine/excels/csvs/GPX.csv")
head(BWGF)## Studies trt.n trt trt.sd con.n con con.sd conc dur hsper
## 1 Ayazi 2014a 50 2001.04 197.2 50 1975.25 197.2 0.25 42 42
## 2 Ayazi 2014b 50 2179.41 197.2 50 1975.25 197.2 0.50 42 42
## 3 Ayazi 2014c 50 2053.05 197.2 50 1975.25 197.2 1.00 42 42
## 4 Bai et al. 2019a 60 804.60 117.4 60 776.30 117.4 0.50 14 14
## 5 Bai et al. 2019b 60 852.30 117.4 60 776.30 117.4 1.00 14 14
## 6 Dai et al. 2011 18 1487.00 813.7 18 1087.00 813.7 0.50 42 21
head(GPX)## Studies trt.n trt trt.sd con.n con con.sd conc dur hsper
## 1 Sifa et al. 2018a1 6 12.36 5.641175 6 6.18 5.641175 0.5 42 1
## 2 Sifa et al. 2018b1 6 13.61 5.641175 6 6.18 5.641175 1.5 42 1
## 3 Sifa et al. 2018c1 6 14.08 5.641175 6 6.18 5.641175 2.0 42 1
## 4 Hu et al. 2020 a1 18 16.19 3.568061 18 11.78 3.568061 0.5 21 21
## 5 Hu et al. 2020 a2 18 15.96 3.568061 18 11.78 3.568061 1.0 21 21
## 6 Hu et al. 2020 a3 18 18.46 3.568061 18 11.78 3.568061 1.5 21 21
## organ
## 1 Breast muscle
## 2 Breast muscle
## 3 Breast muscle
## 4 Breast muscle
## 5 Breast muscle
## 6 Breast muscle
There are two categories of data sets.The growth parameters (an example is BWGF), and antioxidant parameters (an example is GPX). we used the head function to show you the general shape of the data sets. Due to confidentiality reason, the original data sets will be made available upon request. Here is the description of the features:
Studies: name of each studies included;
trt.n: sample size of the treatment group;
trt: mean of the treatment group;
trt.sd: standard deviation of the treatment group;
con.n: sample size of the control group;
con: mean of the control group;
con.sd: standard deviation of the control group;
dur: duration of heat stress (used as covariate);
conc: dietary glutamine concentration;
organ: category of tissue;
As you might see, we will use the “metafor” library to pool effect sizes, perform subgroup analysis and draw forest plots.
Growth parameters forest plots
The growth parameters data was pooled without performing any subgroup analysis. Thus, the forest plots are drawn relatively easily. PS: prior analysis such as sensitivity and baujat plot were performed to determine outlying studies. We will have a separate tutorial discussing this approach. for the time being we assume that the reader is just interested in drawing forest plots after pooling effect sizes. Only the first code chunk will be detailed step by step.
TR<- escalc(m1i = trt, m2i= con,sd1i = trt.sd, sd2i = con.sd, n1i=trt.n,n2i = con.n,
data= BWGF,measure = "SMD") #we calculate effect size
TR %>%
as_tibble() %>%
head() ## then we print the results obtained## # A tibble: 6 x 12
## Studies trt.n trt trt.sd con.n con con.sd conc dur hsper yi vi
## <chr> <int> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <dbl> <dbl>
## 1 Ayazi 20~ 50 2001. 197. 50 1975. 197. 0.25 42 42 0.130 0.0401
## 2 Ayazi 20~ 50 2179. 197. 50 1975. 197. 0.5 42 42 1.03 0.0453
## 3 Ayazi 20~ 50 2053. 197. 50 1975. 197. 1 42 42 0.391 0.0408
## 4 Bai et a~ 60 805. 117. 60 776. 117. 0.5 14 14 0.240 0.0336
## 5 Bai et a~ 60 852. 117. 60 776. 117. 1 14 14 0.643 0.0351
## 6 Dai et a~ 18 1487 814. 18 1087 814. 0.5 42 21 0.481 0.114
New columns yi and vi were added to the original dataset.These are the effect sizes (yi) and their standard error (vi). We will use them to perform the meta-analysis (pool effect sizes) as well as to draw the forest plots. For details about technical terms such as random effects or fixed effects please refer to the manuscript.
res <-rma(yi,vi,method="REML",data = TR,slab = Studies) ## pooling effect sizes (ES) using random effects
res##
## Random-Effects Model (k = 17; tau^2 estimator: REML)
##
## tau^2 (estimated amount of total heterogeneity): 0.1085 (SE = 0.0608)
## tau (square root of estimated tau^2 value): 0.3294
## I^2 (total heterogeneity / total variability): 67.25%
## H^2 (total variability / sampling variability): 3.05
##
## Test for Heterogeneity:
## Q(df = 16) = 50.0152, p-val < .0001
##
## Model Results:
##
## estimate se zval pval ci.lb ci.ub <U+200B>
## 0.7029 0.1023 6.8724 <.0001 0.5024 0.9033 ***
##
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
You can now see the results we will use to draw the forest plot
forest(res,xlim=c(-6, 6), header = "Studies", )
### add text with Q-value, dfs, p-value, and I^2 statistic
text(-0.30, -1, pos=2, cex=0.75, bquote(paste(" for All Studies (Q = ",
.(formatC(res$QE, digits=2, format="f")), ", df = ", .(res$k - res$p),
", p = ", .(formatC(res$QEp, digits=2, format="f")), "; ", I^2, " = ",
.(formatC(res$I2, digits=1, format="f")), "%)")))Antioxidant parameters forest plots
Since subgroup analysis was used in this case, we will have to perform the analysis and then include sections in the forest plot for each subgroups. While the code will get longer, the reasoning stays the same.
TR5<- escalc(m1i = trt, m2i= con,sd1i = trt.sd, sd2i = con.sd, n1i=trt.n,n2i = con.n,
data=GPX,measure = "SMD")
TR5 %>%
as_tibble() %>%
head()## # A tibble: 6 x 13
## Studies trt.n trt trt.sd con.n con con.sd conc dur hsper organ yi
## <chr> <int> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <chr> <dbl>
## 1 Sifa et a~ 6 12.4 5.64 6 6.18 5.64 0.5 42 1 Brea~ 1.01
## 2 Sifa et a~ 6 13.6 5.64 6 6.18 5.64 1.5 42 1 Brea~ 1.22
## 3 Sifa et a~ 6 14.1 5.64 6 6.18 5.64 2 42 1 Brea~ 1.29
## 4 Hu et al.~ 18 16.2 3.57 18 11.8 3.57 0.5 21 21 Brea~ 1.21
## 5 Hu et al.~ 18 16.0 3.57 18 11.8 3.57 1 21 21 Brea~ 1.15
## 6 Hu et al.~ 18 18.5 3.57 18 11.8 3.57 1.5 21 21 Brea~ 1.83
## # ... with 1 more variable: vi <dbl>
res<-rma(yi,vi,method="REML",data = TR5,slab = Studies)
res##
## Random-Effects Model (k = 18; tau^2 estimator: REML)
##
## tau^2 (estimated amount of total heterogeneity): 0.4386 (SE = 0.2395)
## tau (square root of estimated tau^2 value): 0.6623
## I^2 (total heterogeneity / total variability): 65.07%
## H^2 (total variability / sampling variability): 2.86
##
## Test for Heterogeneity:
## Q(df = 17) = 44.4697, p-val = 0.0003
##
## Model Results:
##
## estimate se zval pval ci.lb ci.ub <U+200B>
## 1.1219 0.1982 5.6620 <.0001 0.7336 1.5103 ***
##
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Next we perform the subgroup analysis
res1 <- rma(yi, vi, mods = ~ organ, data=TR5, method = "REML") #test for significant difference in the ES between subgroup
##actually fitting subgroups##
res2 <- rma(yi, vi, subset=(organ=="Thigh muscle"), data=TR5, method = "REML")
res3 <- rma(yi, vi, subset=(organ=="Serum"), data=TR5, method = "REML")
res4 <- rma(yi, vi, subset=(organ=="Breast muscle"), data=TR5, method = "REML")Now comes the tricky part, we draw the forest plot step by step.
### separate subgroups in forest plot now ###
forest(res,xlim=c(-6, 6), ylim = c(-2,34), order = organ, rows=c(3:8,13:18,23:28), header = "Studies", )
##add text on the graph##
### add text with Q-value, dfs, p-value, and I^2 statistic for the whole model##
text(-1.4, -1, pos=2, cex=0.75, bquote(paste(" for All Studies (Q = ",
.(formatC(res$QE, digits=2, format="f")), ", df = ", .(res$k - res$p),
", p = ", .(formatC(res$QEp, digits=2, format="f")), "; ", I^2, " = ",
.(formatC(res$I2, digits=1, format="f")), "%)")))
### add text for the test of subgroup differences
text(-1.4, -2, pos=2, cex=0.75, bquote(paste("Test for Subgroup Differences: ",
Q[M], " = ", .(formatC(res1$QM, digits=2, format="f")), ", df = ", .(res$p - 1),
", p = ", .(formatC(res1$QMp, digits=2, format="f")))))
### add text for the headers of subgroups####
op <- par(cex=1.2, font=4)
text(-6, c(10,20,30), cex=1, pos=4, c("Breast Muscle",
"Serum", "Thigh muscle"))
par(op)
### add text with Q-value, dfs, p-value, and I^2 statistic for the subgroups ###
text(-6, 21.5, pos=4, cex=1, bquote(paste("RE Model for Subgroup (Q = ",
.(formatC(res2$QE, digits=2, format="f")), ", df = ", .(res2$k - res2$p),
", p = ", .(formatC(res2$QEp, digits=2, format="f")), "; ", I^2, " = ",
.(formatC(res2$I2, digits=1, format="f")), "%)")))
text(-6, 11.5, pos=4, cex=1, bquote(paste("RE Model for Subgroup (Q = ",
.(formatC(res3$QE, digits=2, format="f")), ", df = ", .(res3$k - res3$p),
", p = ", .(formatC(res3$QEp, digits=2, format="f")), "; ", I^2, " = ",
.(formatC(res3$I2, digits=1, format="f")), "%)")))
text(-6, 1.5, pos=4, cex=1, bquote(paste("RE Model for Subgroup (Q = ",
.(formatC(res4$QE, digits=2, format="f")), ", df = ", .(res4$k - res4$p),
", p = ", .(formatC(res4$QEp, digits=2, format="f")), "; ", I^2, " = ",
.(formatC(res4$I2, digits=1, format="f")), "%)")))
##add polygons to the subgroups##
addpoly(res2, row=21.5, cex=1, mlab="")
addpoly(res3, row= 11.5, cex=1, mlab="")
addpoly(res4, row= 1.5, cex=1, mlab="") By using the same approaches all remaining forest plots of the manuscript can be plotted.