1 How to use this file

This file is the binary outcome practical. It is designed to be run step by step in RStudio and then knitted to HTML or PDF.

Training question: Does hyaluronidase reduce the risk of binary outcomes such as perineal trauma or episiotomy?

Effect measure: Risk ratio (RR).

Because both outcomes are undesirable:

  • RR < 1 favours hyaluronidase.
  • RR = 1 suggests no relative difference.
  • RR > 1 suggests higher risk in the hyaluronidase group.

Important correction: This analysis estimates risk ratios, not odds ratios. If an older note or Stata graph label says “OR”, that label is incorrect for this workflow.

Training note: Some studies in the dataset are simulated for workshop teaching. Use the dataset to learn the workflow and interpretation, not to make clinical recommendations.

1.1 Package strategy used in this practical

To keep the training simple and consistent, all three practical files use the same small package set:

  • {readxl} to import Excel files
  • {dplyr} to clean and inspect data
  • {meta} to run the standard meta-analyses
  • {knitr} to display clean tables

Teaching note: {metafor} is a powerful advanced package and is excellent for custom analyses. However, for introductory hands-on training, {meta} is more direct because it provides purpose-built functions such as metabin(), metaprop(), and metacont(). We do not use {rmeta} in these final files because it is an older package and is less suitable for a modern, reproducible training workflow.

2 1. Load packages

Run this chunk first. It installs any missing packages and then loads the packages used in the file.

packages <- c("readxl", "dplyr", "meta", "knitr")
missing <- packages[!sapply(packages, requireNamespace, quietly = TRUE)]
if (length(missing) > 0) install.packages(missing)

library(readxl)
library(dplyr)
library(meta)
library(knitr)

2.1 Interpretation

  • What this output is: Usually there is no visible output unless a package is missing or being installed.
  • How to interpret it: No error means the packages are available.
  • Key takeaway: For binary outcomes, the main function in this practical is metabin().
  • Common pitfall: Running this in a very old R installation can cause package installation errors. Use a current CRAN version of R.

3 2. Read the Excel file as a data frame

Keep the Excel dataset in the same folder as this .Rmd file.

data_file <- "Hyaluronidase_MetaAnalysis_Dataset_statafinal1_1.xlsx"
if (!file.exists(data_file)) stop("Put the Hyaluronidase Excel file in the same folder as this Rmd.")

binary_df <- read_excel(data_file, sheet = 1, range = "A5:P45", col_names = TRUE)

names(binary_df) <- c(
  "Study", "ROBOverall", "aHAaseevents", "n1HAasetotal",
  "cControlevents", "n2Controltotal", "RiskHAase", "RiskControl",
  "RR", "lnRR", "SElnRR", "CILower", "CIUpper",
  "Outcome", "TypeofStudy", "RCT_design"
)

3.1 Interpretation

  • What this output is: This imports the Excel sheet and assigns clean variable names.
  • How to interpret it: If no error appears, the file was found and imported successfully.
  • Key takeaway: For binary meta-analysis, the essential columns are intervention events/total and control events/total.
  • Common pitfall: If R cannot find the file, check that the Excel file and .Rmd are in the same folder.

4 3. Inspect and clean the dataset

binary_df <- binary_df %>%
  mutate(
    Study = trimws(Study),
    Outcome = trimws(Outcome),
    RCT_design = trimws(RCT_design),
    ROBOverall = trimws(ROBOverall),
    aHAaseevents = as.numeric(aHAaseevents),
    n1HAasetotal = as.numeric(n1HAasetotal),
    cControlevents = as.numeric(cControlevents),
    n2Controltotal = as.numeric(n2Controltotal)
  )

binary_df %>%
  select(Study, Outcome, RCT_design, aHAaseevents, n1HAasetotal,
         cControlevents, n2Controltotal, ROBOverall) %>%
  head(12) %>%
  kable(caption = "First 12 rows of the binary outcome dataset")
First 12 rows of the binary outcome dataset
Study Outcome RCT_design aHAaseevents n1HAasetotal cControlevents n2Controltotal ROBOverall
Chatfield 1966* Perineal_Trauma Placebo 58 67 62 67 High
Colacioppo 2011* Perineal_Trauma Placebo 86 115 89 113 Low
Kwon 2020* Perineal_Trauma Placebo 61 88 68 86 Low
Martinez 2019 (sim) Perineal_Trauma Placebo 70 95 74 93 Low
Chen 2020 (sim) Perineal_Trauma Placebo 82 110 86 108 Some Concerns
Kumar 2021 (sim) Perineal_Trauma Placebo 55 80 59 78 High
Johansson 2018 (sim) Perineal_Trauma Placebo 48 70 52 68 Some Concerns
Patel 2022 (sim) Perineal_Trauma Placebo 66 92 71 90 Low
Nguyen 2021 (sim) Perineal_Trauma Placebo 44 65 48 63 High
Osei 2020 (sim) Perineal_Trauma Placebo 35 55 38 53 High
Chatfield 1966* Episiotomy Placebo 22 67 28 67 High
Colacioppo 2011* Episiotomy Placebo 41 115 47 113 Low

4.1 Interpretation

  • What this output is: A preview of the cleaned dataset.
  • How to interpret it: Each row is one study-outcome comparison. Events and totals should be plausible and labels should be consistent.
  • Good data look like: Event counts are non-missing, totals are positive, and events do not exceed totals.
  • Key takeaway: The dataset is ready for binary outcome meta-analysis if counts and labels are correct.
  • Common pitfall: Starting the analysis before checking that the event counts correspond to the correct treatment arm.
binary_df %>%
  summarise(
    rows = n(),
    missing_events = sum(is.na(aHAaseevents) | is.na(cControlevents)),
    missing_totals = sum(is.na(n1HAasetotal) | is.na(n2Controltotal)),
    events_exceed_total = sum(aHAaseevents > n1HAasetotal | cControlevents > n2Controltotal, na.rm = TRUE),
    zero_or_negative_total = sum(n1HAasetotal <= 0 | n2Controltotal <= 0, na.rm = TRUE)
  ) %>%
  kable(caption = "Basic data checks")
Basic data checks
rows missing_events missing_totals events_exceed_total zero_or_negative_total
40 0 0 0 0

4.2 Interpretation

  • What this output is: A simple validity check for missing or impossible count data.
  • How to interpret it: Ideally, all problem counts should be zero.
  • Key takeaway: Meta-analysis results are only as credible as the extracted data.
  • Recommended next step: If a problem count is non-zero, inspect the corresponding row before fitting the model.
binary_df %>%
  count(Outcome, RCT_design) %>%
  kable(caption = "Number of studies by outcome and comparison design")
Number of studies by outcome and comparison design
Outcome RCT_design n
Episiotomy No Intervention 10
Episiotomy Placebo 10
Perineal_Trauma No Intervention 10
Perineal_Trauma Placebo 10

4.3 Interpretation

  • What this output is: A count of studies available for each outcome and comparison design.
  • How to interpret it: It shows whether placebo-controlled and no-intervention comparisons are both represented.
  • Key takeaway: Comparison design matters because placebo-controlled and no-intervention studies answer slightly different questions.
  • Common pitfall: Pooling different comparison designs without checking whether subgroup analysis is needed.

5 4. Prepare the placebo-controlled dataset

For the main teaching analysis, we first focus on placebo-controlled studies.

placebo_df <- binary_df %>%
  filter(RCT_design == "Placebo")

placebo_df %>%
  count(Outcome) %>%
  kable(caption = "Placebo-controlled studies by outcome")
Placebo-controlled studies by outcome
Outcome n
Episiotomy 10
Perineal_Trauma 10

5.1 Interpretation

  • What this output is: The number of placebo-controlled studies available for each outcome.
  • How to interpret it: A larger number of studies gives more information, but credibility still depends on study quality and consistency.
  • Key takeaway: The next analyses estimate pooled RRs separately for perineal trauma and episiotomy.

6 5. Fit the binary meta-analysis models

6.1 5.1 Perineal trauma: HAase versus placebo

trauma_placebo_df <- placebo_df %>% filter(Outcome == "Perineal_Trauma")

m_trauma_placebo <- metabin(
  event.e = aHAaseevents,
  n.e = n1HAasetotal,
  event.c = cControlevents,
  n.c = n2Controltotal,
  studlab = Study,
  data = trauma_placebo_df,
  sm = "RR",
  method = "MH",
  common = FALSE,
  random = TRUE,
  method.tau = "REML",
  method.random.ci = "HK"
)

summary(m_trauma_placebo)
##                          RR           95%-CI %W(random)
## Chatfield 1966*      0.9355 [0.8328; 1.0508]       20.3
## Colacioppo 2011*     0.9495 [0.8230; 1.0954]       13.4
## Kwon 2020*           0.8767 [0.7348; 1.0459]        8.8
## Martinez 2019 (sim)  0.9260 [0.7905; 1.0848]       11.0
## Chen 2020 (sim)      0.9362 [0.8098; 1.0822]       13.1
## Kumar 2021 (sim)     0.9089 [0.7485; 1.1036]        7.3
## Johansson 2018 (sim) 0.8967 [0.7296; 1.1021]        6.5
## Patel 2022 (sim)     0.9094 [0.7695; 1.0746]        9.9
## Nguyen 2021 (sim)    0.8885 [0.7149; 1.1042]        5.8
## Osei 2020 (sim)      0.8876 [0.6831; 1.1531]        4.0
## 
## Number of studies: k = 10
## Number of observations: o = 1656 (o.e = 837, o.c = 819)
## Number of events: e = 1252
## 
##                          RR           95%-CI      t  p-value
## Random effects model 0.9193 [0.9021; 0.9368] -10.08 < 0.0001
## 
## Quantifying heterogeneity (with 95%-CIs):
##  tau^2 = 0; tau = 0; I^2 = 0.0% [0.0%; 62.4%]; H = 1.00 [1.00; 1.63]
## 
## Test of heterogeneity:
##     Q d.f. p-value
##  0.88    9  0.9997
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = 9)

6.2 Interpretation

  • What this output is: A random-effects meta-analysis of risk ratios for perineal trauma in placebo-controlled studies.
  • How to interpret it: The pooled result is RR = 0.919 (95% CI 0.902 to 0.937). Because RR is below 1, the point estimate favours hyaluronidase.
  • Heterogeneity: I2 = 0.0%, tau2 = 0.0000, Q-test p = 1.000.
  • Key takeaway: The result suggests a lower relative risk of perineal trauma in the HAase group in this teaching dataset.
  • What cannot be concluded: This result alone does not prove clinical benefit; certainty also depends on risk of bias, directness, publication bias, and whether the simulated studies are excluded in a real review.
  • Common pitfall: Interpreting the p-value as the size or importance of the effect. The RR and its CI are more informative.

6.3 5.2 Episiotomy: HAase versus placebo

epi_placebo_df <- placebo_df %>% filter(Outcome == "Episiotomy")

m_epi_placebo <- metabin(
  event.e = aHAaseevents,
  n.e = n1HAasetotal,
  event.c = cControlevents,
  n.c = n2Controltotal,
  studlab = Study,
  data = epi_placebo_df,
  sm = "RR",
  method = "MH",
  common = FALSE,
  random = TRUE,
  method.tau = "REML",
  method.random.ci = "HK"
)

summary(m_epi_placebo)
##                          RR           95%-CI %W(random)
## Chatfield 1966*      0.7857 [0.5040; 1.2249]        8.8
## Colacioppo 2011*     0.8572 [0.6171; 1.1907]       16.1
## Kwon 2020*           0.7996 [0.5292; 1.2082]       10.2
## Martinez 2019 (sim)  0.8702 [0.5946; 1.2735]       12.0
## Chen 2020 (sim)      0.8677 [0.6137; 1.2267]       14.5
## Kumar 2021 (sim)     0.8357 [0.5344; 1.3070]        8.7
## Johansson 2018 (sim) 0.7771 [0.4789; 1.2611]        7.4
## Patel 2022 (sim)     0.8106 [0.5448; 1.2059]       11.0
## Nguyen 2021 (sim)    0.7930 [0.4726; 1.3307]        6.5
## Osei 2020 (sim)      0.7495 [0.4164; 1.3491]        5.0
## 
## Number of studies: k = 10
## Number of observations: o = 1656 (o.e = 837, o.c = 819)
## Number of events: e = 580
## 
##                          RR           95%-CI      t  p-value
## Random effects model 0.8248 [0.7966; 0.8539] -12.53 < 0.0001
## 
## Quantifying heterogeneity (with 95%-CIs):
##  tau^2 = 0; tau = 0; I^2 = 0.0% [0.0%; 62.4%]; H = 1.00 [1.00; 1.63]
## 
## Test of heterogeneity:
##     Q d.f. p-value
##  0.47    9  1.0000
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = 9)

6.4 Interpretation

  • What this output is: A random-effects meta-analysis of risk ratios for episiotomy in placebo-controlled studies.
  • How to interpret it: The pooled result is RR = 0.825 (95% CI 0.797 to 0.854). Because RR is below 1, the point estimate favours hyaluronidase.
  • Heterogeneity: I2 = 0.0%, tau2 = 0.0000, Q-test p = 1.000.
  • Key takeaway: The teaching dataset suggests fewer episiotomies in the HAase group.
  • Common pitfall: Reporting “17% lower odds” when the analysis used a risk ratio. The correct interpretation is relative risk reduction when RR < 1.

7 6. Summary table

rr_results <- bind_rows(
  summary_rr(m_trauma_placebo, "Perineal trauma: placebo-controlled"),
  summary_rr(m_epi_placebo, "Episiotomy: placebo-controlled")
)

rr_results %>%
  mutate(
    RR = fmt_num(RR),
    Lower_95_CI = fmt_num(Lower_95_CI),
    Upper_95_CI = fmt_num(Upper_95_CI),
    Tau2 = fmt_num(Tau2, 4),
    I2_percent = fmt_num(I2_percent, 1),
    Q_p_value = fmt_p(Q_p_value)
  ) %>%
  kable(caption = "Pooled risk ratios using random-effects REML and Hartung-Knapp CIs")
Pooled risk ratios using random-effects REML and Hartung-Knapp CIs
Analysis Studies RR Lower_95_CI Upper_95_CI Tau2 I2_percent Q_p_value
Perineal trauma: placebo-controlled 10 0.919 0.902 0.937 0.0000 0.0 1.000
Episiotomy: placebo-controlled 10 0.825 0.797 0.854 0.0000 0.0 1.000

7.1 Interpretation

  • What this output is: A compact table of the pooled effect estimates and heterogeneity statistics.
  • How to interpret it: RR values below 1 favour HAase for these undesirable outcomes.
  • Good vs. concerning: Narrow CIs and low heterogeneity are easier to interpret; wide CIs or high heterogeneity require more caution.
  • Key takeaway: This table is useful for reporting and for comparing outcomes.
  • Recommended next step: Inspect forest plots to see the study-level estimates and weights.

8 7. Forest plots

8.1 7.1 Perineal trauma forest plot

forest(
  m_trauma_placebo,
  prediction = TRUE,
  print.tau2 = TRUE,
  print.I2 = TRUE,
  leftcols = c("studlab", "event.e", "n.e", "event.c", "n.c"),
  leftlabs = c("Study", "HAase events", "HAase total", "Control events", "Control total"),
  rightcols = c("effect", "ci", "w.random"),
  rightlabs = c("RR", "95% CI", "Weight"),
  xlab = "Risk Ratio (RR)",
  smlab = "HAase vs placebo"
)

8.2 Interpretation

  • What this output is: A forest plot showing each study RR, 95% CI, weight, and the pooled RR.
  • How to interpret it: Squares are study estimates, horizontal lines are CIs, and the diamond is the pooled estimate.
  • Key takeaway: If the diamond is left of RR = 1, the pooled result favours HAase.
  • Assumptions and limitations: A forest plot does not assess risk of bias by itself; it only displays statistical results.
  • Recommended next step: Compare the visual pattern with the heterogeneity statistics.

8.3 7.2 Episiotomy forest plot

forest(
  m_epi_placebo,
  prediction = TRUE,
  print.tau2 = TRUE,
  print.I2 = TRUE,
  leftcols = c("studlab", "event.e", "n.e", "event.c", "n.c"),
  leftlabs = c("Study", "HAase events", "HAase total", "Control events", "Control total"),
  rightcols = c("effect", "ci", "w.random"),
  rightlabs = c("RR", "95% CI", "Weight"),
  xlab = "Risk Ratio (RR)",
  smlab = "HAase vs placebo"
)

8.4 Interpretation

  • What this output is: A forest plot for episiotomy in placebo-controlled studies.
  • How to interpret it: The pooled diamond summarises the average RR under the random-effects model.
  • Key takeaway: The plot should be interpreted alongside heterogeneity, risk of bias, and clinical comparability.
  • Common pitfall: Treating a precise pooled estimate as automatically trustworthy. Precision is not the same as validity.

9 8. Sensitivity to tau-squared estimator

This section asks: Would the result change if we used a different estimator for between-study variance?

The only thing we change below is method.tau.

fit_binary_rr <- function(data, tau_method = "REML") {
  metabin(
    event.e = aHAaseevents,
    n.e = n1HAasetotal,
    event.c = cControlevents,
    n.c = n2Controltotal,
    studlab = Study,
    data = data,
    sm = "RR",
    method = "MH",
    common = FALSE,
    random = TRUE,
    method.tau = tau_method,
    method.random.ci = "HK"
  )
}
tau_results <- bind_rows(
  summary_rr(fit_binary_rr(epi_placebo_df, "REML"), "Episiotomy - REML"),
  summary_rr(fit_binary_rr(epi_placebo_df, "DL"),   "Episiotomy - DL"),
  summary_rr(fit_binary_rr(epi_placebo_df, "SJ"),   "Episiotomy - SJ")
)

tau_results %>%
  mutate(
    RR = fmt_num(RR),
    Lower_95_CI = fmt_num(Lower_95_CI),
    Upper_95_CI = fmt_num(Upper_95_CI),
    Tau2 = fmt_num(Tau2, 4),
    I2_percent = fmt_num(I2_percent, 1),
    Q_p_value = fmt_p(Q_p_value)
  ) %>%
  kable(caption = "Sensitivity of pooled RR to tau-squared estimator")
Sensitivity of pooled RR to tau-squared estimator
Analysis Studies RR Lower_95_CI Upper_95_CI Tau2 I2_percent Q_p_value
Episiotomy - REML 10 0.825 0.797 0.854 0.0000 0.0 1.000
Episiotomy - DL 10 0.825 0.797 0.854 0.0000 0.0 1.000
Episiotomy - SJ 10 0.825 0.797 0.854 0.0001 0.0 1.000

9.1 Interpretation

  • What this output is: A sensitivity table comparing different between-study variance estimators.
  • How to interpret it: If REML, DL, and SJ give similar RRs and CIs, the conclusion is less dependent on the chosen estimator.
  • Good vs. concerning: Similar results are reassuring; large differences suggest the model choice matters.
  • Key takeaway: Model choices should be reported, not hidden.
  • Common pitfall: Using DerSimonian-Laird by default without checking robustness.

10 9. Leave-one-out analysis

10.1 9.1 Perineal trauma

loo_trauma <- metainf(m_trauma_placebo, pooled = "random")
summary(loo_trauma)
## Leave-one-out meta-analysis
## 
##                                   RR           95%-CI  p-value tau^2 tau I^2
## Omitting Chatfield 1966*      0.9152 [0.8958; 0.9350] < 0.0001     0   0  0%
## Omitting Colacioppo 2011*     0.9147 [0.8975; 0.9321] < 0.0001     0   0  0%
## Omitting Kwon 2020*           0.9235 [0.9077; 0.9396] < 0.0001     0   0  0%
## Omitting Martinez 2019 (sim)  0.9185 [0.8989; 0.9384] < 0.0001     0   0  0%
## Omitting Chen 2020 (sim)      0.9168 [0.8977; 0.9363] < 0.0001     0   0  0%
## Omitting Kumar 2021 (sim)     0.9201 [0.9009; 0.9397] < 0.0001     0   0  0%
## Omitting Johansson 2018 (sim) 0.9209 [0.9023; 0.9398] < 0.0001     0   0  0%
## Omitting Patel 2022 (sim)     0.9204 [0.9010; 0.9402] < 0.0001     0   0  0%
## Omitting Nguyen 2021 (sim)    0.9212 [0.9031; 0.9396] < 0.0001     0   0  0%
## Omitting Osei 2020 (sim)      0.9206 [0.9024; 0.9392] < 0.0001     0   0  0%
##                                                                             
## Random effects model          0.9193 [0.9021; 0.9368] < 0.0001     0   0  0%
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = {8, 9})
forest(loo_trauma, xlab = "Risk Ratio (RR)")

10.2 Interpretation

  • What this output is: The pooled RR recalculated after omitting one study at a time.
  • How to interpret it: Compare each omit-one result with the original pooled result: RR = 0.919 (95% CI 0.902 to 0.937).
  • Observed range: Leave-one-out RRs range from 0.915 to 0.924.
  • Key takeaway: If the range is narrow and remains below 1, the result is not driven by a single study.
  • Common pitfall: Removing an influential study without a methodological reason.

10.3 9.2 Episiotomy

loo_epi <- metainf(m_epi_placebo, pooled = "random")
summary(loo_epi)
## Leave-one-out meta-analysis
## 
##                                   RR           95%-CI  p-value tau^2 tau I^2
## Omitting Chatfield 1966*      0.8286 [0.7983; 0.8600] < 0.0001     0   0  0%
## Omitting Colacioppo 2011*     0.8187 [0.7880; 0.8506] < 0.0001     0   0  0%
## Omitting Kwon 2020*           0.8277 [0.7963; 0.8603] < 0.0001     0   0  0%
## Omitting Martinez 2019 (sim)  0.8188 [0.7896; 0.8490] < 0.0001     0   0  0%
## Omitting Chen 2020 (sim)      0.8177 [0.7886; 0.8479] < 0.0001     0   0  0%
## Omitting Kumar 2021 (sim)     0.8237 [0.7921; 0.8567] < 0.0001     0   0  0%
## Omitting Johansson 2018 (sim) 0.8287 [0.7991; 0.8594] < 0.0001     0   0  0%
## Omitting Patel 2022 (sim)     0.8265 [0.7945; 0.8598] < 0.0001     0   0  0%
## Omitting Nguyen 2021 (sim)    0.8270 [0.7962; 0.8589] < 0.0001     0   0  0%
## Omitting Osei 2020 (sim)      0.8289 [0.8013; 0.8575] < 0.0001     0   0  0%
##                                                                             
## Random effects model          0.8248 [0.7966; 0.8539] < 0.0001     0   0  0%
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = {8, 9})
forest(loo_epi, xlab = "Risk Ratio (RR)")

10.4 Interpretation

  • What this output is: A leave-one-out analysis for episiotomy.
  • How to interpret it: Compare omit-one results with the original pooled result: RR = 0.825 (95% CI 0.797 to 0.854).
  • Observed range: Leave-one-out RRs range from 0.818 to 0.829.
  • Key takeaway: Stability across omissions supports robustness, but it does not remove risk-of-bias concerns.
  • Recommended next step: Inspect any study whose omission materially changes the estimate.

11 10. Galbraith/radial plots

11.1 10.1 Perineal trauma

galbraith_plot(m_trauma_placebo, main = "Galbraith plot: perineal trauma")

11.2 Interpretation

  • What this output is: A radial plot of standardized study effects against study precision.
  • How to interpret it: The solid line is the pooled-effect line. The two dashed lines are approximate +/-1.96 reference limits, not the pooled-effect CI.
  • Key takeaway: Points outside the dashed lines may be outliers or sources of heterogeneity.
  • Common pitfall: Automatically deleting studies outside the limits. First check design, population, intervention, comparator, outcome definition, and extracted data.

11.3 10.2 Episiotomy

galbraith_plot(m_epi_placebo, main = "Galbraith plot: episiotomy")

11.4 Interpretation

  • What this output is: A Galbraith/radial plot for episiotomy.
  • How to interpret it: Studies far from the pooled-effect line deserve investigation.
  • Key takeaway: This is a diagnostic plot, not a rule for excluding studies.
  • Recommended next step: If a study looks unusual, compare it with the extraction sheet and risk-of-bias assessment.

12 11. Funnel plots and Egger tests

12.1 11.1 Funnel plots

funnel(m_trauma_placebo, xlab = "log(RR)", main = "Funnel plot: perineal trauma")

funnel(m_epi_placebo, xlab = "log(RR)", main = "Funnel plot: episiotomy")

12.2 Interpretation

  • What this output is: Funnel plots showing study effects against their precision.
  • How to interpret it: Symmetry is reassuring; asymmetry may suggest small-study effects, publication bias, selective reporting, heterogeneity, or chance.
  • Key takeaway: Funnel plots are screening tools, not proof of publication bias.
  • Common pitfall: Over-interpreting funnel plots when the number of studies is small.

12.3 11.2 Egger tests

egger_trauma <- metabias(m_trauma_placebo, method.bias = "linreg", k.min = 3)
egger_epi <- metabias(m_epi_placebo, method.bias = "linreg", k.min = 3)

egger_trauma
## Linear regression test of funnel plot asymmetry
## 
## Test result: t = -3.45, df = 8, p-value = 0.0087
## Bias estimate: -1.0487 (SE = 0.3039)
## 
## Details:
## - multiplicative residual heterogeneity variance (tau^2 = 0.0441)
## - predictor: standard error
## - weight:    inverse variance
## - reference: Egger et al. (1997), BMJ
egger_epi
## Linear regression test of funnel plot asymmetry
## 
## Test result: t = -4.56, df = 8, p-value = 0.0018
## Bias estimate: -1.1171 (SE = 0.2447)
## 
## Details:
## - multiplicative residual heterogeneity variance (tau^2 = 0.0163)
## - predictor: standard error
## - weight:    inverse variance
## - reference: Egger et al. (1997), BMJ

12.4 Interpretation

  • What this output is: Egger regression tests for funnel plot asymmetry.
  • How to interpret it: Small p-values suggest evidence of asymmetry, but they do not identify the cause.
  • Observed results: Perineal trauma p = 0.009; episiotomy p = 0.002.
  • Key takeaway: Treat this as a signal for investigation, not as definitive evidence of publication bias.
  • Recommended next step: Examine funnel plots, study sizes, risk of bias, and clinical heterogeneity together.

13 12. Trim-and-fill sensitivity analysis

tf_trauma <- trimfill(m_trauma_placebo)
tf_epi <- trimfill(m_epi_placebo)

summary(tf_trauma)
##                               RR           95%-CI %W(random)
## Chatfield 1966*           0.9355 [0.8328; 1.0508]       17.1
## Colacioppo 2011*          0.9495 [0.8230; 1.0954]       11.3
## Kwon 2020*                0.8767 [0.7348; 1.0459]        7.4
## Martinez 2019 (sim)       0.9260 [0.7905; 1.0848]        9.2
## Chen 2020 (sim)           0.9362 [0.8098; 1.0822]       11.0
## Kumar 2021 (sim)          0.9089 [0.7485; 1.1036]        6.1
## Johansson 2018 (sim)      0.8967 [0.7296; 1.1021]        5.4
## Patel 2022 (sim)          0.9094 [0.7695; 1.0746]        8.3
## Nguyen 2021 (sim)         0.8885 [0.7149; 1.1042]        4.9
## Osei 2020 (sim)           0.8876 [0.6831; 1.1531]        3.4
## Filled: Nguyen 2021 (sim) 0.9690 [0.7797; 1.2044]        4.9
## Filled: Osei 2020 (sim)   0.9700 [0.7466; 1.2603]        3.4
## Filled: Kwon 2020*        0.9821 [0.8232; 1.1716]        7.4
## 
## Number of studies: k = 13 (with 3 added studies)
## Number of observations: o = 2066 (o.e = 1045, o.c = 1021)
## Number of events: e = 1546
## 
##                          RR           95%-CI     t  p-value
## Random effects model 0.9279 [0.9096; 0.9465] -8.20 < 0.0001
## 
## Quantifying heterogeneity (with 95%-CIs):
##  tau^2 = 0; tau = 0; I^2 = 0.0% [0.0%; 56.6%]; H = 1.00 [1.00; 1.52]
## 
## Test of heterogeneity:
##     Q d.f. p-value
##  1.66   12  0.9998
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = 12)
## - Trim-and-fill method to adjust for funnel plot asymmetry (L-estimator)
funnel(tf_trauma, xlab = "log(RR)", main = "Trim-and-fill: perineal trauma")

summary(tf_epi)
##                                  RR           95%-CI %W(random)
## Chatfield 1966*              0.7857 [0.5040; 1.2249]        6.9
## Colacioppo 2011*             0.8572 [0.6171; 1.1907]       12.6
## Kwon 2020*                   0.7996 [0.5292; 1.2082]        8.0
## Martinez 2019 (sim)          0.8702 [0.5946; 1.2735]        9.4
## Chen 2020 (sim)              0.8677 [0.6137; 1.2267]       11.3
## Kumar 2021 (sim)             0.8357 [0.5344; 1.3070]        6.8
## Johansson 2018 (sim)         0.7771 [0.4789; 1.2611]        5.8
## Patel 2022 (sim)             0.8106 [0.5448; 1.2059]        8.6
## Nguyen 2021 (sim)            0.7930 [0.4726; 1.3307]        5.1
## Osei 2020 (sim)              0.7495 [0.4164; 1.3491]        3.9
## Filled: Nguyen 2021 (sim)    0.8966 [0.5343; 1.5046]        5.1
## Filled: Chatfield 1966*      0.9049 [0.5805; 1.4107]        6.9
## Filled: Johansson 2018 (sim) 0.9149 [0.5638; 1.4847]        5.8
## Filled: Osei 2020 (sim)      0.9487 [0.5270; 1.7076]        3.9
## 
## Number of studies: k = 14 (with 4 added studies)
## Number of observations: o = 2164 (o.e = 1094, o.c = 1070)
## Number of events: e = 747
## 
##                          RR           95%-CI      t  p-value
## Random effects model 0.8432 [0.8138; 0.8737] -10.37 < 0.0001
## 
## Quantifying heterogeneity (with 95%-CIs):
##  tau^2 = 0; tau = 0; I^2 = 0.0% [0.0%; 55.0%]; H = 1.00 [1.00; 1.49]
## 
## Test of heterogeneity:
##     Q d.f. p-value
##  0.99   13  1.0000
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = 13)
## - Trim-and-fill method to adjust for funnel plot asymmetry (L-estimator)
funnel(tf_epi, xlab = "log(RR)", main = "Trim-and-fill: episiotomy")

13.1 Interpretation

  • What this output is: An exploratory adjustment for funnel plot asymmetry.
  • How to interpret it: Compare the adjusted pooled estimate with the original pooled estimate.
  • Key takeaway: If trim-and-fill changes the conclusion, missing evidence may be important; if it does not, the result is more robust to this specific sensitivity check.
  • Assumptions and limitations: Trim-and-fill relies on strong assumptions and can be misleading when asymmetry is caused by heterogeneity rather than publication bias.
  • Common pitfall: Calling trim-and-fill a “correction.” It is better described as an exploratory sensitivity analysis.

14 13. Subgroup analysis by comparison design

Now we compare placebo-controlled and no-intervention studies.

m_epi_design <- metabin(
  event.e = aHAaseevents,
  n.e = n1HAasetotal,
  event.c = cControlevents,
  n.c = n2Controltotal,
  studlab = Study,
  data = binary_df %>% filter(Outcome == "Episiotomy"),
  sm = "RR",
  method = "MH",
  common = FALSE,
  random = TRUE,
  method.tau = "REML",
  method.random.ci = "HK",
  subgroup = RCT_design
)

summary(m_epi_design)
##                          RR           95%-CI %W(random)      RCT_design
## Chatfield 1966*      0.7857 [0.5040; 1.2249]        5.5         Placebo
## Colacioppo 2011*     0.8572 [0.6171; 1.1907]       10.1         Placebo
## Kwon 2020*           0.7996 [0.5292; 1.2082]        6.4         Placebo
## Martinez 2019 (sim)  0.8702 [0.5946; 1.2735]        7.5         Placebo
## Chen 2020 (sim)      0.8677 [0.6137; 1.2267]        9.1         Placebo
## Kumar 2021 (sim)     0.8357 [0.5344; 1.3070]        5.5         Placebo
## Johansson 2018 (sim) 0.7771 [0.4789; 1.2611]        4.7         Placebo
## Patel 2022 (sim)     0.8106 [0.5448; 1.2059]        6.9         Placebo
## Nguyen 2021 (sim)    0.7930 [0.4726; 1.3307]        4.1         Placebo
## Osei 2020 (sim)      0.7495 [0.4164; 1.3491]        3.2         Placebo
## Chatfield 1966*      0.6192 [0.4106; 0.9338]        6.5 No Intervention
## O'Leary 1965*        0.6364 [0.3696; 1.0958]        3.7 No Intervention
## Scarabotto 2008*     0.6280 [0.3844; 1.0260]        4.5 No Intervention
## Fernando 2017 (sim)  0.4833 [0.2581; 0.9051]        2.8 No Intervention
## Diallo 2019 (sim)    0.4808 [0.2504; 0.9231]        2.6 No Intervention
## Park 2018 (sim)      0.5204 [0.3060; 0.8850]        3.9 No Intervention
## Ahmed 2020 (sim)     0.4828 [0.2682; 0.8689]        3.2 No Intervention
## Rossi 2021 (sim)     0.5185 [0.3114; 0.8633]        4.2 No Intervention
## Williams 2022 (sim)  0.4960 [0.2797; 0.8795]        3.3 No Intervention
## Tanaka 2016 (sim)    0.4792 [0.2402; 0.9557]        2.3 No Intervention
## 
## Number of studies: k = 20
## Number of observations: o = 2858 (o.e = 1448, o.c = 1410)
## Number of events: e = 971
## 
##                          RR           95%-CI     t  p-value
## Random effects model 0.7077 [0.6383; 0.7848] -7.00 < 0.0001
## 
## Quantifying heterogeneity (with 95%-CIs):
##  tau^2 = 0 [0.0000; 0.0505]; tau = 0 [0.0000; 0.2248]
##  I^2 = 0.0% [0.0%; 48.0%]; H = 1.00 [1.00; 1.39]
## 
## Test of heterogeneity:
##      Q d.f. p-value
##  16.26   19  0.6398
## 
## Results for subgroups (random effects model):
##                                k     RR           95%-CI tau^2 tau    Q  I^2
## RCT_design = Placebo          10 0.8248 [0.7966; 0.8539]     0   0 0.47 0.0%
## RCT_design = No Intervention  10 0.5451 [0.4994; 0.5950]     0   0 1.75 0.0%
## 
## Test for subgroup differences (random effects model):
##                    Q d.f.  p-value
## Between groups 98.73    1 < 0.0001
## 
## Details of meta-analysis methods:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Q-Profile method for confidence interval of tau^2 and tau
## - Calculation of I^2 based on Q
## - Hartung-Knapp adjustment for random effects model (df = 19)
forest(m_epi_design, xlab = "Risk Ratio (RR)", prediction = TRUE, print.tau2 = TRUE)

14.1 Interpretation

  • What this output is: A subgroup meta-analysis comparing episiotomy results by comparison design.
  • How to interpret it: Look at the pooled RR within each subgroup and the test for subgroup differences.
  • Good vs. concerning: A large subgroup difference suggests the comparator type may modify the estimated effect.
  • Key takeaway: Placebo and no-intervention comparisons may not be interchangeable.
  • Common pitfall: Interpreting subgroup differences causally. Subgroup analysis is observational within a meta-analysis.
  • Recommended next step: Pre-specify subgroup analyses in the protocol and interpret them with caution.

15 14. Report-ready wording

For placebo-controlled studies, hyaluronidase was associated with a pooled RR of 0.919 (95% CI 0.902 to 0.937) for perineal trauma and 0.825 (95% CI 0.797 to 0.854) for episiotomy using a random-effects Mantel-Haenszel model with REML estimation of between-study variance and Hartung-Knapp confidence intervals. Heterogeneity was I2 = 0.0%, tau2 = 0.0000, Q-test p = 1.000 for perineal trauma and I2 = 0.0%, tau2 = 0.0000, Q-test p = 1.000 for episiotomy. These findings should be interpreted together with study risk of bias, comparison design, sensitivity analyses, and the fact that some records are simulated for training.

16 15. Key learning points

  • Use metabin() for binary outcomes with event counts and total sample sizes.
  • Report the effect measure correctly: this analysis uses RR, not OR.
  • Interpret RR direction in relation to whether the outcome is desirable or undesirable.
  • Forest plots show study-level and pooled estimates; they do not assess risk of bias.
  • Leave-one-out analysis checks influence, not validity.
  • Funnel plots, Egger tests, and trim-and-fill are exploratory diagnostics, not definitive proof of publication bias.