Skip to contents

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).

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

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^*}}$$

Author

ChatGPT (Jing Hua Zhao)

Examples

if (FALSE) { # \dontrun{
## ------------------------------------------------------------------
## Classic GIANT consortium example (historical demo)
## Speliotes, Elizabeth K., M.D. [[email protected]]
## 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)
} # }