Meta-analysis forest plot
Pool studies with fixed-effect and random-effects meta-analysis and draw a forest plot with heterogeneity, I² and a prediction interval.
A clear answer. Here’s how.
Each study contributes an estimate yᵢ and a variance vᵢ. From 2×2 counts the log risk ratio has variance 1/a − 1/n₁ + 1/c − 1/n₂ and the log odds ratio 1/a + 1/b + 1/c + 1/d; a study with a zero cell gets 0.5 added to all four cells, and a study with no events (or only events) in both groups is excluded, as the Cochrane Handbook advises. An estimate with 95% limits gives SE = (upper − lower) ÷ (2 × 1.96) on the log scale for ratios. The fixed-effect estimate weights each study by 1/vᵢ. Cochran’s Q = Σ wᵢ(yᵢ − ȳ)² on k − 1 degrees of freedom tests heterogeneity, I² = (Q − df) ÷ Q (floored at 0) is the share of variation beyond chance, and the DerSimonian–Laird τ² = (Q − df) ÷ (Σw − Σw² ÷ Σw) is the between-study variance. Random-effects weights are 1/(vᵢ + τ²) and the interval is normal; the optional Hartung–Knapp interval rescales the standard error and uses t with k − 1 df, which is wider and better behaved with few studies. The prediction interval for a new study is the random-effects estimate ± t(k − 2) × √(τ² + SE²) (Higgins, Thompson and Spiegelhalter 2009); metafor’s default uses z instead, so its interval is narrower. Ratios are pooled on the log scale and shown back-transformed. It does not assess risk of bias or publication bias, fit meta-regression or other τ² estimators (REML, Paule–Mandel), or use Mantel–Haenszel or Peto weights. It is a calculator, not a substitute for a statistician when decisions depend on the answer.
How this is checked
5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.
See the checks and where each expected answer comes from
Case 1
- Inputs
- The tool’s default inputs
- Expected, and what Toolmoz gave
- Pooled estimate, random effects expected 0.48962415046361907, Toolmoz 0.48962415046361995% CI lower limit, random effects expected 0.344919135222476, Toolmoz 0.3449191352224767595% CI upper limit, random effects expected 0.6950377182251471, Toolmoz 0.6950377182251455Tau-squared (DerSimonian–Laird) expected 0.30876026286237646, Toolmoz 0.30876026286237646I-squared expected 92.11734685456207, Toolmoz 92.11734685456207Q statistic (heterogeneity) expected 152.2330080823734, Toolmoz 152.2330080823734Pooled estimate, fixed effect expected 0.6503236196194822, Toolmoz 0.6503236196194822
- Where the expected answer comes from
- BCG trials: metafor rma(measure “RR”, method “DL”) on dat.bcg reports a pooled risk ratio of exp(−0.7141) = 0.4896 (0.3449 to 0.6950), τ² = 0.3088, I² = 92.12% and Q = 152.2330 on 12 df; full precision from an independent Python script
- Allowed difference
- ±1e-9 relative
Case 2
- Inputs
- Effect measure for counts OR
- Expected, and what Toolmoz gave
- Pooled estimate, random effects expected 0.4735999269141501, Toolmoz 0.473599926914150295% CI lower limit, random effects expected 0.3249055971091039, Toolmoz 0.324905597109104895% CI upper limit, random effects expected 0.6903448040563273, Toolmoz 0.6903448040563256Tau-squared (DerSimonian–Laird) expected 0.3663434067255993, Toolmoz 0.3663434067255992Pooled estimate, fixed effect expected 0.6465278030935879, Toolmoz 0.6465278030935879
- Where the expected answer comes from
- BCG trials as odds ratios: log OR = log(ad ÷ bc) with variance 1/a + 1/b + 1/c + 1/d, pooled by the same inverse-variance and DerSimonian–Laird formulas in an independent Python script
- Allowed difference
- ±1e-9 relative
Case 3
- Inputs
- Random-effects interval yes
- Expected, and what Toolmoz gave
- 95% CI lower limit, Hartung–Knapp expected 0.3302777360257432, Toolmoz 0.330277736025745195% CI upper limit, Hartung–Knapp expected 0.7258491341315693, Toolmoz 0.725849134131564995% prediction interval, lower limit expected 0.1354925670682173, Toolmoz 0.135492567068216895% prediction interval, upper limit expected 1.7693354986515344, Toolmoz 1.7693354986515404
- Where the expected answer comes from
- metafor’s Hartung–Knapp fit of the BCG risk ratios gives the log interval −1.1078 to −0.3204 (SE 0.1807, t with 12 df); prediction interval exp(−0.7141 ± t(11) × √(0.30876 + 0.17874²)); both in an independent Python script with its own t quantiles
- Allowed difference
- ±1e-7 relative
Case 4
- Inputs
- Studies, one per line A,0.5,0.2 B,0.2,0.1 C,0.8,0.25Each line holds effectEffects are difference
- Expected, and what Toolmoz gave
- Pooled estimate, fixed effect expected 0.3212765957446808, Toolmoz 0.3212765957446808Q statistic (heterogeneity) expected 5.9361702127659575, Toolmoz 5.9361702127659575Tau-squared (DerSimonian–Laird) expected 0.061666666666666675, Toolmoz 0.06166666666666664P-value for heterogeneity expected 0.05140164483341251, Toolmoz 0.05140164483341256Pooled estimate, random effects expected 0.44441712467457334, Toolmoz 0.4444171246745733
- Where the expected answer comes from
- By hand: weights 1/0.2² = 25, 1/0.1² = 100 and 1/0.25² = 16, so the fixed effect is (12.5 + 20 + 12.8) ÷ 141 = 45.3/141; Q = Σ w(y − 0.3213)² = 5.9362; τ² = (Q − 2) ÷ (141 − 10881/141) = 0.06167; with 2 df the heterogeneity p-value is exp(−Q/2)
- Allowed difference
- ±1e-12
Case 5
- Inputs
- Studies, one per line Trial 1,0.75,0.60,0.94 Trial 2,0.90,0.70,1.16 Trial 3,0.62,0.45,0.85Each line holds interval
- Expected, and what Toolmoz gave
- Pooled estimate, fixed effect expected 0.7662954102053182, Toolmoz 0.7662954102053181Pooled estimate, random effects expected 0.7606782023527384, Toolmoz 0.7606782023527386Tau-squared (DerSimonian–Laird) expected 0.011581826324660134, Toolmoz 0.011581826324659896
- Where the expected answer comes from
- Hazard ratios with 95% limits: log HR and SE = (log upper − log lower) ÷ (2 × 1.959964), pooled in an independent Python script
- Allowed difference
- ±1e-9
What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.
See a worked example
Worked example
A fixed demonstration, separate from the values you enter above.
- Studies, one per line
study,cases_vaccinated,n_vaccinated,cases_control,n_control Aronson 1948,4,123,11,139 Ferguson & Simes 1949,6,306,29,303 Rosenthal et al 1960,3,231,11,220 Hart & Sutherland 1977,62,13598,248,12867 Frimodt-Moller et al 1973,33,5069,47,5808 Stein & Aronson 1953,180,1541,372,1451 Vandiviere et al 1973,8,2545,10,629 TPT Madras 1980,505,88391,499,88391 Coetzee & Berjak 1968,29,7499,45,7277 Rosenthal et al 1961,17,1716,65,1665 Comstock et al 1974,186,50634,141,27338 Comstock & Webster 1969,5,2498,3,2341 Comstock et al 1976,27,16913,29,17854
- Column separator
- Detect automatically
- Each line holds
- Events and total in group 1, then in group 2 (2×2 counts)
- Effect measure for counts
- Risk ratio
- Effects are
- Ratios (odds, risk or hazard ratios)
- Random-effects interval
- Normal (z) interval
- Confidence level
- 95%
Example result
| Study | Events / total, group 1 | Events / total, group 2 | Risk ratio | 95% CI lower | 95% CI upper | Weight, fixed effect (%) | Weight, random effects (%) |
|---|---|---|---|---|---|---|---|
| Aronson 1948 | 4 / 123 | 11 / 139 | 0.410938654841 | 0.134301570833 | 1.25739838332 | 0.503754802568 | 5.03649168323 |
| Ferguson & Simes 1949 | 6 / 306 | 29 / 303 | 0.204868154158 | 0.0862974496336 | 0.486352270738 | 0.842912651727 | 6.34732918264 |
| Rosenthal et al 1960 | 3 / 231 | 11 / 220 | 0.25974025974 | 0.0734425906881 | 0.918608696914 | 0.394866486318 | 4.41202722473 |
| Hart & Sutherland 1977 | 62 / 13598 | 248 / 12867 | 0.236560523606 | 0.179280894081 | 0.312140797912 | 8.19663305961 | 9.71764635681 |
| Frimodt-Moller et al 1973 | 33 / 5069 | 47 / 5808 | 0.804489533795 | 0.516293127127 | 1.25355805836 | 3.20277948823 | 8.87537738166 |
Risk ratios are pooled on the log scale and shown back-transformed. Fixed effect: inverse-variance weights 1/vᵢ. Random effects: DerSimonian–Laird τ² added to each variance. The prediction interval (t, 11 df) is where the effect of a new study is expected to fall. Pooling is only as good as the studies: check their risk of bias and whether they are similar enough to combine.