Back to Blog
Guides
5 min read

From GUI to R Code: Making Your Meta-Analysis Reproducible with metafor

Point-and-click software gets results, but reviewers increasingly demand reproducible R code. This guide bridges the gap, explaining every line of metafor output so you can move from GUI to fully reproducible meta-analysis scripts with confidence.

Dr. Sarah Mitchell

April 17, 2026

Want to try this yourself? Use our free research tools, no sign-up required.

Key Takeaways

rma() fits the meta-analytic model. The method argument controls the heterogeneity estimator, with "REML" as best practice.

forest() produces the visualization. Customize with slab, order, refline, and addpred.

funnel() visualizes potential publication bias. The yaxis and shade arguments give you control.

metabias() provides formal asymmetry tests. Report the method, statistic, and p-value.

Our free tools auto-generate complete, runnable metafor scripts from your data with one-click copy.

A reproducible script deposited in a public repository satisfies PRISMA 2020 transparency requirements.

Reproducibility is no longer optional in research synthesis. Journal editors, peer reviewers, and systematic review protocols increasingly require that every analytical decision be documented in code that others can audit, re-run, and verify. If you have been running your meta-analysis through a graphical interface, you already understand the statistics. What you need now is the reproducible meta-analysis R code equivalent, line by line, so every reviewer and co-author can replicate your findings independently.

Our free tools at Research Gold auto-generate ready-to-run metafor R code the moment you enter your data. This guide covers every core function, customization technique, and best practice for building a shareable R script.

Why Reproducibility Has Become Non-Negotiable

The replication crisis has made method transparency a gatekeeping criterion at major journals. The PRISMA 2020 statement (Page et al., 2021) emphasizes transparency of analytical choices, and many Cochrane Handbook protocols mandate that R or Stata code be deposited alongside the final review. Journals such as Nature, The BMJ, and The Lancet now enforce code-sharing policies that reject manuscripts without a reproducible pipeline.

Reproducible code also protects you. When a reviewer asks you to exclude a single study and re-run the analysis, a well-commented R script lets you answer in minutes rather than days.

Understanding the metafor Package Architecture

Function architecture of the metafor R package
metafor package: function architecture

metafor, developed by Wolfgang Viechtbauer (2010), is the most widely cited R package for meta-analysis on CRAN. The R Core Team maintains the language, while Viechtbauer provides regular updates tracking evolving standards.

escalc(): Computing Effect Sizes

Before fitting any model, you need standardized effect sizes and their sampling variances. The escalc() function handles this conversion:

library(metafor)
dat <- escalc(measure = "SMD",
              m1i = mean_treat, sd1i = sd_treat, n1i = n_treat,
              m2i = mean_ctrl, sd2i = sd_ctrl, n2i = n_ctrl,
              data = raw_data)

The measure argument accepts over 30 effect size types including "SMD", "OR", "RR", "COR", and "ZCOR". The function creates two columns: yi (computed effect size) and vi (sampling variance). Our free Cohen's d calculator generates this code block with your data pre-filled.

rma(): Your Model Engine

Every meta-analysis in metafor starts with rma():

res <- rma(yi, vi, data = dat, method = "REML")
summary(res)

The method argument specifies the heterogeneity estimator, with "REML" (restricted maximum likelihood) as best practice per the Cochrane Handbook (Higgins et al., 2023). Try our free forest plot creator to auto-generate this code with your own data.

forest(), funnel(), and metabias()

forest() produces the visualization. funnel() plots effect sizes against precision for publication bias assessment. metabias() runs formal asymmetry tests (Egger's regression, Begg's rank correlation, Peters' test). Generate configured plot scripts with our build a funnel plot.

Complete R Script Template for Random-Effects Meta-Analysis

Below is a complete, copy-ready R script following the workflow recommended in the Cochrane Handbook and by Viechtbauer (2010):

# ============================================================
# Reproducible Random-Effects Meta-Analysis
# Author: [Your Name]  |  Date: [Today's Date]
# Software: R + metafor package
# ============================================================

library(metafor)

# Load data
dat <- data.frame(
  study  = c("Smith 2018","Jones 2019","Lee 2020","Garcia 2021","Patel 2022"),
  mean_t = c(12.4, 15.1, 11.8, 14.2, 13.6),
  sd_t   = c(3.2, 4.1, 2.9, 3.8, 3.5),
  n_t    = c(45, 62, 38, 54, 71),
  mean_c = c(10.1, 12.8, 10.5, 11.9, 11.2),
  sd_c   = c(3.5, 3.9, 3.1, 4.0, 3.3),
  n_c    = c(43, 58, 40, 52, 68))

# Compute effect sizes (Hedges' g)
dat <- escalc(measure = "SMD",
              m1i = mean_t, sd1i = sd_t, n1i = n_t,
              m2i = mean_c, sd2i = sd_c, n2i = n_c,
              data = dat)

# Fit random-effects model
res <- rma(yi, vi, data = dat, method = "REML")
summary(res)

# Forest plot with prediction interval
forest(res, slab = dat$study, header = TRUE,
       xlab = "Standardized Mean Difference (Hedges' g)",
       addpred = TRUE)

# Funnel plot + Egger's test
funnel(res, xlab = "SMD")
metabias(res, method = "linreg")

# Leave-one-out sensitivity
leave1out(res)

# Session info for reproducibility
sessionInfo()

Replace the sample data with your own values and adjust the measure argument for your outcome type. For a broader introduction, see our complete meta-analysis in R guide.

Forest Plot Customization in metafor

Journal submissions often require specific formatting. Here is how to control every visual element of the forest plot:

forest(res, slab = dat$study,
       header = c("Study", "SMD [95% CI]"),
       xlab = "Standardized Mean Difference",
       refline = 0, addpred = TRUE, order = "obs",
       col = "navy", border = "navy", shade = TRUE,
       fonts = "serif", cex = 0.85,
       xlim = c(-3, 4), alim = c(-2, 3))

# Add pooled estimate annotation
text(-3, -1.5, pos = 4, cex = 0.75, font = 2,
     bquote(paste("Pooled SMD = ",
     .(formatC(res$beta, format="f", digits=2)),
     " (95% CI: ", .(formatC(res$ci.lb, format="f", digits=2)),
     ", ", .(formatC(res$ci.ub, format="f", digits=2)), ")")))

Key parameters: fonts accepts "serif", "sans", or "mono". cex controls text size. col and border set diamond and square colors. shade = TRUE alternates row shading. order = "obs" sorts by effect size, while "prec" sorts by precision. For interactive creation, try our browser-based forest plot.

Need help with your meta-analysis?

Our PhD statisticians run complete meta-analyses: effect sizes, forest plots, heterogeneity testing, and publication-ready results sections.

Adding Funnel Plots and Publication Bias Tests

A robust publication bias assessment requires both visual inspection and formal tests:

# Contour-enhanced funnel plot
funnel(res, xlab = "SMD", yaxis = "sei",
       level = c(0.10, 0.05, 0.01),
       shade = c("white","gray85","gray70","gray55"),
       legend = TRUE)

# Formal tests
metabias(res, method = "linreg")  # Egger's test

# Trim-and-fill for adjusted estimate
tf <- trimfill(res)
summary(tf)
funnel(tf, xlab = "SMD")

# Fail-safe N
fsn(yi, vi, data = dat, type = "Rosenthal")

The contour-enhanced funnel plot overlays significance regions so you can distinguish publication bias from other asymmetry sources. The trim-and-fill method (Duval and Tweedie, 2000) estimates missing studies and produces an adjusted pooled estimate. For a visual approach, use our funnel plot creator.

Sensitivity Analysis and Influence Diagnostics Code

Sensitivity analysis determines whether your result depends on any single study:

# Leave-one-out analysis
l1o <- leave1out(res)
print(l1o)

# Visualize as forest plot
forest(l1o$estimate, sei = l1o$se,
       slab = paste0("Omitting ", dat$study),
       xlab = "SMD", refline = coef(res),
       header = c("Study Omitted", "SMD [95% CI]"))

# Influence diagnostics
inf <- influence(res)
plot(inf)

# Baujat plot (contribution vs. influence)
baujat(res)

The leave-one-out analysis re-fits the model k times, each time dropping one study. The Baujat plot (Baujat et al., 2002) maps each study's contribution to heterogeneity against its influence on the pooled result. Our leave-one-out calculator generates interactive leave-one-out visualizations with downloadable R code.

Subgroup Analysis Code with metafor

Subgroup analysis tests whether the treatment effect varies across pre-specified categories. In metafor, the preferred approach uses the mods argument for a mixed-effects model:

dat$subgroup <- c("RCT", "Quasi", "RCT", "RCT", "Quasi")

# Mixed-effects model with subgroup moderator
res_sub <- rma(yi, vi, mods = ~ subgroup,
               data = dat, method = "REML")
summary(res_sub)

# Report Q-between statistic
cat("QM =", round(res_sub$QM, 3),
    ", p =", round(res_sub$QMp, 4), "\n")

# Subgroup-specific models for forest plot
res_rct   <- rma(yi, vi, data = dat,
                 subset = (subgroup == "RCT"), method = "REML")
res_quasi <- rma(yi, vi, data = dat,
                 subset = (subgroup == "Quasi"), method = "REML")

Report the Q-between statistic and its p-value to indicate whether the subgroup difference is statistically significant. For a full walkthrough of subgroup techniques, see our guide on how to do meta-analysis step by step.

Need expert help structuring your meta-analysis workflow from protocol to publication? Our biostatisticians build fully reproducible R-based analysis pipelines for systematic reviews and meta-analyses across every discipline. request your project quote or explore our meta-analysis package to see how we can support your next project.

How to Create a Reproducible R Project

A reproducible R project packages your code, data, and environment into a self-contained folder that anyone can run on any machine.

my-meta-analysis/
  |-- data/raw_data.csv, codebook.md
  |-- scripts/01_data_prep.R, 02_main_analysis.R,
  |           03_sensitivity.R, 04_figures.R
  |-- output/figures/, tables/
  |-- renv.lock
  |-- README.md
  |-- my-meta-analysis.Rproj

Locking Package Versions with renv

The renv package (Ushey, 2023) captures the exact version of every R package. When a collaborator runs renv::restore(), they get your identical package stack, including the same metafor version and the same tidyverse version (Wickham, 2023):

renv::init()       # Initialize
renv::snapshot()   # Lock current versions
renv::restore()    # Collaborator restores exact environment

Your README should list the research question, data sources, script execution order, expected outputs, and software requirements.

Sharing Code with Reviewers and Co-Authors

The two dominant sharing platforms are GitHub and the Open Science Framework (OSF). GitHub tracks every change, so co-authors see what was modified and when. Tag your final analysis with a release version (v1.0) before submission. The Open Science Framework provides DOI-minted project pages for supplementary deposits accepted by PLOS, Wiley, and Springer Nature.

Include sessionInfo() output in every script, add inline comments explaining decisions, and use relative file paths so scripts run on any machine.

Journal Requirements for Statistical Code Sharing

Code sharing is becoming mandatory across top-tier publications. Nature requires code in a public repository (GitHub, Zenodo, or Code Ocean). The BMJ mandates that "statistical analysis plan, including code" be available and encourages PROSPERO pre-registration. The Lancet requires a reproducibility statement for meta-analyses. Cochrane Library reviews must document methods for replication. PLOS ONE enforces strict open-code policy at publication.

Deposit your code in a DOI-minted repository (Zenodo, OSF, or Figshare) before submission and include the DOI in your manuscript.

Common R Errors and How to Fix Them

Even experienced R users encounter cryptic errors in meta-analysis code. Here are the most frequent issues and their solutions.

escalc() errors: "length of 'm1i' and 'm2i' do not match" means unequal row counts; use complete.cases() to filter. "negative sampling variance" indicates a data entry error in standard deviation columns.

rma() errors: "Fisher scoring algorithm did not converge" usually means extreme outliers or very small k. Try method = "DL" as a fallback. "Studies with NAs omitted" means rows lack yi or vi; remove NAs explicitly.

forest() errors: "length of 'slab' does not match" means labels do not match filtered data. For overlapping text, reduce cex (try 0.65 for 20+ studies) and widen xlim.

General tips: run update.packages() before starting and use str(dat) to confirm column types.

Converting Research Gold Tool Output to R Scripts

Translating Research Gold tool clicks into reproducible R metafor code
From GUI clicks to reproducible R code

Every interactive tool in the Research Gold free tools hub generates production-ready metafor R code alongside its visual output.

Enter your data, click "Generate R Code," paste into RStudio, customize, and save. The forest plot drag-and-drop tool outputs a complete pipeline (escalc(), rma(), forest()). The sensitivity analysis calculator adds leave1out() and influence() diagnostics. The free effect size tool outputs the exact escalc() call for your outcome type. Start with a validated code block and extend it.

Customizing Auto-Generated Code

Common customizations: changing the effect measure (measure = "OR" for odds ratios), adding prediction intervals (addpred = TRUE), switching the heterogeneity estimator (method = "DL" when REML does not converge), and adding meta-regression with mods = ~ year. For our biostatistics services, we deliver every analysis with a complete, commented R project.

Key Takeaways

  • escalc() computes effect sizes and variances from raw data, supporting over 30 outcome types
  • rma() fits the meta-analytic model, with "REML" as the recommended heterogeneity estimator per the Cochrane Handbook
  • forest() produces publication-quality visualizations with full control over fonts, colors, and annotations
  • funnel() and metabias() provide visual and formal publication bias assessment, supplemented by trim-and-fill
  • Sensitivity analysis with leave1out() and influence diagnostics identify studies with outsized leverage
  • Subgroup analysis via the mods argument tests effect modification across pre-specified categories
  • renv locks your package environment so collaborators reproduce your exact R setup
  • GitHub and OSF provide version-controlled sharing that satisfies journal transparency policies
  • Our free tools auto-generate complete, runnable metafor scripts from your data with one-click copy
  • A reproducible script deposited in a DOI-minted repository satisfies PRISMA 2020 transparency requirements

Reproducibility is a key advantage of code-based tools. Compare software alternatives to RevMan for reproducible analysis to find the best fit for your next systematic review.

Frequently Asked Questions

5
rma() fits models for independent effect sizes, one per study. rma.mv() is the multivariate extension for datasets where studies contribute multiple correlated effect sizes. If your meta-analysis has one effect size per study, use rma().
REML is currently recommended. DerSimonian-Laird remains common but consistently underestimates tau-squared in small samples. Paule-Mandel performs well when the number of studies is small.
Yes. Add the mods argument using standard R formula syntax. Meta-regression requires at least ten studies per moderator variable to avoid overfitting.
Compute the variance from the confidence interval: vi = ((upper_ci - lower_ci) / (2 * 1.96))^2. Or use escalc() to compute from raw data.
The scripts assume pre-computed effect sizes and variances. If you need to compute from raw data, add an escalc() step before rma(). Need help with your systematic review or meta-analysis? [Get a free quote](/get-a-quote) from our team of PhD researchers.
Share

Found this useful? Share it with your colleagues.

Need help with your meta-analysis?

Our PhD statisticians run complete meta-analyses: effect sizes, forest plots, heterogeneity testing, and publication-ready results sections.

Explore our Meta-Analysis Service, handled end-to-end by a PhD methodologist.

Meta-Analysis Support

Reading About Meta-Analysis? Our PhD Team Runs Them Every Day.

From data extraction to forest plots, sensitivity analysis, and a journal-ready manuscript. We handle the full meta-analysis so you can focus on your research question.

Our promise: Free re-run of the pooled analysis if reviewers question the estimate or model.

4.9 / 5Quote within a few hoursmetafor R + Cochrane HandbookPhD methodologistConfidential by default
Chat on WhatsApp now
DS

Written by

Dr. Sarah Mitchell

PhD, Biostatistics & Research Methodology
Systematic Review MethodologyMeta-AnalysisBiostatistics

Dr. Sarah Mitchell holds a PhD in Biostatistics from Johns Hopkins Bloomberg School of Public Health and has over 15 years of experience in systematic review methodology and meta-analysis. She has authored or co-authored 40+ peer-reviewed publications in journals including the Journal of Clinical Epidemiology, BMC Medical Research Methodology, and Research Synthesis Methods. A former Cochrane Review Group statistician and current editorial board member of Systematic Reviews, Dr. Mitchell has supervised 200+ evidence synthesis projects across clinical medicine, public health, and social sciences.

Need professional help with your systematic review or meta-analysis? Get a free quote from our team of PhD researchers.

Reading About Meta-Analysis? Our PhD Team Runs Them Every Day.

From data extraction to forest plots, sensitivity analysis, and a journal-ready manuscript. We handle the full meta-analysis so you can focus on your research question.

Starting from the research question, not just the data? We run the whole systematic review and meta-analysis together. Quote my review + meta-analysis

Quote within a few hours. Pay only after you approve your quote. Unlimited revisions within your agreed scope. Confidential by default.