# Meta Analysis

> Use when performing meta-analysis, pooling study data, generating forest plots, funnel plots, assessing heterogeneity, or conducting subgroup and sensitivity analyses. Invoke for any statistical synthesis of multiple studies.

- Skill: `majiayu000/meta-analysis` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/meta-analysis`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/meta-analysis/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/meta-analysis

---


# Meta-Analysis Skill

This skill guides statistical synthesis of multiple studies using R.

## When to Use

Invoke this skill when the user:
- Asks to pool study results or combine data
- Requests forest plot or funnel plot
- Asks about heterogeneity (I², Q, tau²)
- Wants subgroup or sensitivity analysis
- Mentions "meta-analysis" or "synthesis"
- Needs publication bias assessment

## R Packages Required

```r
library(meta)      # Primary meta-analysis package
library(metafor)   # Advanced methods
library(dmetar)    # Companion functions
```

## Analysis Types

### Binary Outcomes (OR, RR, RD)

Use `metabin()` for dichotomous data:

```r
ma <- metabin(
    event.e = events_intervention,
    n.e = n_intervention,
    event.c = events_control,
    n.c = n_control,
    studlab = study_id,
    data = data,
    sm = "OR",        # "RR" for Risk Ratio, "RD" for Risk Difference
    method = "MH",    # Mantel-Haenszel
    random = TRUE,    # Random-effects model
    prediction = TRUE # Prediction interval
)
summary(ma)
```

### Continuous Outcomes (MD, SMD)

Use `metacont()` for continuous data:

```r
ma <- metacont(
    n.e = n_intervention,
    mean.e = mean_intervention,
    sd.e = sd_intervention,
    n.c = n_control,
    mean.c = mean_control,
    sd.c = sd_control,
    studlab = study_id,
    data = data,
    sm = "SMD",      # "MD" for Mean Difference
    random = TRUE
)
```

### Single-Arm Proportions

Use `metaprop()` for single-arm rates:

```r
ma <- metaprop(
    event = events,
    n = total,
    studlab = study_id,
    data = data,
    sm = "PLOGIT",   # Logit transformation
    random = TRUE
)
```

### Hazard Ratios (Time-to-Event)

Use `metagen()` for pre-calculated HRs:

```r
ma <- metagen(
    TE = log(HR),
    seTE = (log(HR_upper) - log(HR_lower)) / 3.92,
    studlab = study_id,
    data = data,
    sm = "HR",
    random = TRUE
)
```

## Forest Plot

```r
# Save to file (required for non-interactive sessions)
png("forest_plot.png", width=1200, height=800, res=150)

forest(ma,
    sortvar = TE,                    # Sort by effect size
    xlim = c(0.1, 10),              # X-axis limits for OR/RR
    at = c(0.1, 0.25, 0.5, 1, 2, 4, 10),
    leftcols = c("studlab", "n.e", "n.c"),
    leftlabs = c("Study", "n (Int)", "n (Ctrl)"),
    rightcols = c("effect", "ci"),
    rightlabs = c("OR", "95% CI"),
    prediction = TRUE                # Show prediction interval
)

dev.off()
```

## Heterogeneity Interpretation

| I² Value | Interpretation |
|----------|----------------|
| 0-25% | Low heterogeneity |
| 25-50% | Moderate heterogeneity |
| 50-75% | Substantial heterogeneity |
| >75% | Considerable heterogeneity |

Key statistics to report:
- **I²**: Percentage of variability due to heterogeneity
- **τ²**: Between-study variance (tau-squared)
- **Q**: Cochran's Q statistic and p-value
- **Prediction interval**: Range of true effects

## Subgroup Analysis

```r
# By categorical variable
update(ma, subgroup = study_design, tau.common = FALSE)

# Forest plot with subgroups
forest(ma, subgroup = study_design, test.subgroup = TRUE)
```

## Sensitivity Analysis

```r
# Leave-one-out analysis
metainf(ma, pooled = "random")

# Influence diagnostics
influence(ma)

# Exclude high risk of bias studies
ma_low_rob <- update(ma, subset = rob_overall != "High")
```

## Publication Bias

```r
# Funnel plot
png("funnel_plot.png", width=800, height=600, res=150)
funnel(ma, studlab = TRUE)
dev.off()

# Egger's test (recommended for >10 studies)
metabias(ma, method.bias = "Egger")

# Begg's test (rank correlation)
metabias(ma, method.bias = "Begg")

# Trim-and-fill
tf <- trimfill(ma)
summary(tf)
funnel(tf)
```

## Output Requirements

Always report:
1. Number of studies and total participants
2. Pooled effect estimate with 95% CI
3. P-value for overall effect
4. I² with interpretation
5. τ² (for random-effects)
6. Prediction interval (if using random-effects)
7. Publication bias tests (if ≥10 studies)

## Example Complete Analysis

```r
library(meta)

# Load data
data <- read.csv("extraction_data.csv")

# Meta-analysis
ma <- metabin(
    event.e = events_int, n.e = n_int,
    event.c = events_ctrl, n.c = n_ctrl,
    studlab = study_id, data = data,
    sm = "OR", method = "MH", random = TRUE
)

# Results
summary(ma)

# Forest plot
png("forest_plot.png", width=1200, height=800, res=150)
forest(ma, sortvar=TE, prediction=TRUE)
dev.off()

# Funnel plot
png("funnel_plot.png", width=800, height=600, res=150)
funnel(ma)
dev.off()

# Publication bias
metabias(ma, method.bias="Egger")

# Sensitivity
metainf(ma)
```

