metap: Meta-analysis of p-values with heterogeneity and random...

View source: R/metap.R

metapR Documentation

Meta-analysis of p-values with heterogeneity and random effects

Description

Performs GWAS-style meta-analysis by combining p-values across studies. Implements Fisher’s method, fixed-effect weighted Stouffer Z, and random-effects Z meta-analysis with heterogeneity statistics.

Usage

metap(
  data,
  N,
  sided = c("two", "one"),
  verbose = TRUE,
  prefixp = "p",
  prefixn = "n",
  prefixbeta = NULL,
  prefixdir = NULL
)

Arguments

data

data.frame containing study results.

N

number of studies.

sided

"two" (default) or "one" for one-sided p-values.

verbose

logical; print summary output.

prefixp

prefix for p-value columns (default "p").

prefixn

prefix for sample-size columns (default "n").

prefixbeta

optional prefix for beta columns (used for direction).

prefixdir

optional prefix for sign columns (+1/-1).

Details

This function implements the meta-analysis approach used in the Genetic Investigation of ANThropometric Traits (GIANT) consortium.

Missing studies are automatically excluded per row, so the number of contributing studies may vary across variants.

Fisher’s method

X^2 = -2 \sum_{i=1}^k \log(p_i) \sim \chi^2_{2k}

Fixed-effect weighted Stouffer Z

Convert p-values to Z:

z_i = \Phi^{-1}(1 - p_i/2)

Sample-size weights:

w_i = \sqrt{n_i}

Z_{FE} = \frac{\sum w_i z_i}{\sqrt{\sum w_i^2}}

Heterogeneity

Q = \sum w_i (z_i - \bar z)^2

I^2 = \max(0, (Q-(k-1))/Q)

Random-effects Z meta-analysis

DerSimonian–Laird variance:

\tau^2 = \max\left(0,\frac{Q-(k-1)}{\sum w_i - \sum w_i^2/\sum w_i}\right)

Random-effects weights:

w_i^* = 1/(1/w_i + \tau^2)

Z_{RE} = \frac{\sum w_i^* z_i}{\sqrt{\sum w_i^*}}

Value

data.frame with

  • fisher_p Fisher combined p-value

  • stouffer_FE Fixed-effect Z meta p-value

  • stouffer_RE Random-effects Z meta p-value

  • Q Cochran heterogeneity statistic

  • I2 Proportion heterogeneity

  • tau2 Between-study variance

Author(s)

ChatGPT (Jing Hua Zhao)

Examples

## Not run: 
## ------------------------------------------------------------------
## Classic GIANT consortium example (historical demo)
## Speliotes, Elizabeth K., M.D. [ESPELIOTES@PARTNERS.ORG]
## 22-2-2008 MRC-Epid JHZ
## ------------------------------------------------------------------

s <- data.frame(
  p1 = 0.1^rep(8:2, each = 7),
  n1 = rep(32000, 49),
  p2 = 0.1^rep(8:2, times = 7),
  n2 = rep(8000, 49)
)

res <- metap(s, 2)
head(res)

## Visual comparison equal vs unequal N (original demo)

np <- 7
p  <- 0.1^((np + 1):2)
z  <- qnorm(1 - p/2)
n  <- c(32000, 8000)

grid <- expand.grid(i = seq_len(np), j = seq_len(np))
za <- z[grid$i]; zb <- z[grid$j]

metaz_equalN   <- (sqrt(n[1])*za + sqrt(n[1])*zb)/sqrt(n[1]+n[1])
metaz_unequalN <- (sqrt(n[1])*za + sqrt(n[2])*zb)/sqrt(n[1]+n[2])

q  <- -log10(sort(p, decreasing=TRUE))
t1 <- matrix(-log10(sort(2*pnorm(-abs(metaz_equalN))),   decreasing=TRUE), np, np)
t2 <- matrix(-log10(sort(2*pnorm(-abs(metaz_unequalN))), decreasing=TRUE), np, np)

par(mfrow=c(1,2), bg="white", mar=c(4.2,3.8,0.2,0.2))
persp(q,q,t1, main="Equal sample sizes")
persp(q,q,t2, main="Unequal sample sizes")

## ------------------------------------------------------------------
## New example: missing studies + heterogeneity
## ------------------------------------------------------------------

set.seed(1)
dat <- data.frame(
  p1 = runif(100,1e-6,0.05),
  n1 = sample(5000:20000,100,TRUE),
  p2 = runif(100,1e-6,0.05),
  n2 = sample(5000:20000,100,TRUE)
)

## simulate missing studies
dat$p2[sample(1:100,20)] <- NA

res <- metap(dat,2)
summary(res$I2)

## End(Not run)


gap documentation built on May 28, 2026, 9:07 a.m.