Package {MAIVE}


Type: Package
Title: Meta Analysis Instrumental Variable Estimator
Encoding: UTF-8
Version: 0.3.0
RoxygenNote: 7.3.3
URL: https://meta-analysis.cz/maive/, https://github.com/PetrCala/MAIVE
BugReports: https://github.com/PetrCala/MAIVE/issues
Description: Meta-analysis traditionally assigns more weight to studies with lower standard errors, assuming higher precision. However, in observational research, precision must be estimated and is vulnerable to manipulation, such as p-hacking, to achieve statistical significance. This can lead to spurious precision, invalidating inverse-variance weighting and bias-correction methods like funnel plots. Common methods for addressing publication bias, including selection models, often fail or exacerbate the problem. This package introduces an instrumental variable approach to limit bias caused by spurious precision in meta-analysis. Methods are described in 'Irsova et al.' (2025) <doi:10.1038/s41467-025-63261-0>.
License: MIT + file LICENSE
Depends: R (≥ 4.0.0)
Imports: stats, cli, clubSandwich
Suggests: testthat, knitr, rmarkdown, varhandle, metafor
VignetteBuilder: knitr
NeedsCompilation: no
Packaged: 2026-09-03 11:39:18 UTC; runner
Author: Zuzana Irsova [aut] (affiliation: Charles University, Prague), Pedro R. D. Bom [aut] (affiliation: University of Deusto, Bilbao), Tomas Havranek [aut] (affiliation: Charles University, Prague; CEPR, London; METRICS, Stanford), Heiko Rachinger [aut] (affiliation: University of the Balearic Islands, Palma), Petr Cala [aut, cre] (affiliation: Charles University, Prague)
Maintainer: Petr Cala <cala.p@seznam.cz>
Repository: CRAN
Date/Publication: 2026-09-03 14:30:22 UTC

MAIVE: Meta Analysis Instrumental Variable Estimator

Description

Meta-analysis traditionally assigns more weight to studies with lower standard errors, assuming higher precision. However, in observational research, precision must be estimated and is vulnerable to manipulation, such as p-hacking, to achieve statistical significance. This can lead to spurious precision, invalidating inverse-variance weighting and bias-correction methods like funnel plots. Common methods for addressing publication bias, including selection models, often fail or exacerbate the problem. This package introduces an instrumental variable approach to limit bias caused by spurious precision in meta-analysis. Methods are described in 'Irsova et al.' (2025) doi:10.1038/s41467-025-63261-0.

Author(s)

Maintainer: Petr Cala cala.p@seznam.cz (Charles University, Prague)

Authors:

See Also

Useful links:


Joint Anderson-Rubin CI computation

Description

Computes AR confidence intervals using a 2D grid search over (b0, b1) with chi^2_2 critical value. For the slope (Egger) coefficient under weak instruments, use method = "slope_only" instead.

Usage

compute_AR_CI_optimized(
  model,
  adjust_fun,
  bs,
  sebs,
  invNs,
  g,
  type_choice,
  weights = NULL,
  method = "joint"
)

Arguments

model

Fitted lm object from second-stage regression

adjust_fun

PET_adjust or PEESE_adjust function

bs

Effect estimates

sebs

Standard errors

invNs

Inverse sample sizes (instrument)

g

Cluster variable

type_choice

CR variance type ("CR0", "CR1", "CR2")

weights

Optional weights for weighted AR

method

"joint" for 2D grid, "slope_only" for subset AR (robust under weak IV)


Subset Anderson-Rubin CI for the slope coefficient

Description

Computes weak-instrument-robust AR confidence interval for the slope (Egger) coefficient by treating the intercept as a nuisance parameter.

Usage

compute_AR_CI_slope_only(
  model,
  adjust_fun,
  bs,
  sebs,
  invNs,
  g,
  type_choice,
  weights = NULL
)

Details

This method is robust under weak instruments and avoids the "banana projection" artifact that can produce spuriously narrow CIs when projecting from 2D joint AR regions.

Algorithm (per tjhavranek, Nov 2025): 1. For each candidate slope b1, form residuals: r_i = y_i - b1 * x_i 2. Run auxiliary regression: r ~ 1 + z (intercept absorbs b0) 3. Use cluster-robust (CR2) variance for the z coefficient 4. Test statistic: t_z^2 from the clustered test 5. Accept b1 if t_z^2 <= qchisq(0.95, df = 1) = 3.84

References: - Guggenberger, P., Kleibergen, F. (2012). Econometrica. - Andrews, D. W. K., & Mikusheva, A. (2016). Econometrica.


Draw a funnel plot (base graphics)

Description

High-level wrapper that accepts the original input data and the result returned by 'maive()' / 'waive()', prepares the necessary vectors/metadata, and draws the funnel plot on the currently active graphics device.

Usage

get_funnel_plot(dat, result, instrument = NULL, model_type = "MAIVE")

Arguments

dat

Data frame containing at least numeric columns 'bs' (effect sizes) and 'sebs' (standard errors).

result

Result list returned by 'maive()' or 'waive()'.

instrument

Optional indicator (0/1). If 'NULL', inferred from 'result'.

model_type

Label used for plot text/legend (e.g., '"MAIVE"' or '"WAIVE"').

Details

Device management (PNG/SVG/PDF, resolution, base64 encoding) is intentionally left to the caller.

Value

Invisibly returns 'NULL'.


R code for MAIVE

Description

R package for MAIVE: "Spurious Precision in Meta-Analysis of Observational Research" by Zuzana Irsova, Pedro Bom, Tomas Havranek, Petr Cala, and Heiko Rachinger.

Usage

maive(
  dat,
  method,
  weight,
  instrument,
  studylevel,
  SE,
  AR,
  first_stage = 0L,
  estimate = NULL,
  se = NULL,
  n = NULL,
  study_id = NULL,
  seed = 123
)

Arguments

dat

Data frame with columns bs, sebs, Ns, study_id (optional). Column names can be remapped with estimate, se, n, and study_id.

method

1 FAT-PET, 2 PEESE, 3 PET-PEESE, 4 EK.

weight

0 no weights, 1 standard weights, 2 MAIVE adjusted weights, 3 study weights.

instrument

1 yes, 0 no.

studylevel

Correlation at study level: 0 none, 1 fixed effects, 2 cluster.

SE

SE estimator: 0 CR0 (Huber-White), 1 CR1 (Standard empirical correction), 2 CR2 (Bias-reduced estimator), 3 wild bootstrap.

AR

Anderson Rubin corrected CI for weak instruments (available for unweighted and MAIVE-adjusted weight versions of PET, PEESE, PET-PEESE, not available for fixed effects): 0 no, 1 yes.

first_stage

First-stage specification for the variance model: 0 levels, 1 log.

estimate

Optional column name to use instead of 'bs'

se

Optional column name to use instead of 'sebs'

n

Optional column name to use instead of 'Ns'

study_id

Optional column name for study identifiers. When not supplied, a column named study_id is used if present; otherwise, if dat has four or more columns, the fourth column is used as the study identifier and a warning names the column. Any fourth column (a moderator, a year) would otherwise drive the study dummies and clustering at every studylevel other than 0, so name the column explicitly or drop it.

seed

Seed for the wild bootstrap when SE = 3. Use NULL to avoid setting a seed (results depend on the current RNG state). Default is 123 for historical reproducibility.

Details

Guided, interactive workflow available at https://www.easymeta.org.

Data dat can be imported from an Excel file via: dat <- read_excel("inputdata.xlsx") or from a csv file via: dat <- read.csv("inputdata.csv") It should contain:

Default option for MAIVE: MAIVE-PET-PEESE, unweighted, instrumented, cluster SE, wild bootstrap, AR.

Value

Examples

dat <- data.frame(
  bs = c(0.5, 0.45, 0.55, 0.6),
  sebs = c(0.25, 0.2, 0.22, 0.27),
  Ns = c(50, 80, 65, 90)
)

result <- maive(dat,
  method = 3, weight = 0, instrument = 1,
  studylevel = 0, SE = 0, AR = 0, first_stage = 0
)


Convert metafor objects into MAIVE input data

Description

Builds the data frame that maive() and waive() expect (columns bs, sebs, Ns, and optionally study_id) from a metafor escalc data frame or an rma.uni model fit.

Usage

maive_from_metafor(x, ni = NULL, study_id = NULL)

Arguments

x

An escalc data frame (or any data frame with yi and vi columns) or an rma.uni fit.

ni

Optional sample sizes: a numeric vector, or the name of a column in x (or in the data stored with the fit). Overrides any sample sizes carried by x.

study_id

Optional study identifiers: a vector, or the name of a column in x (or in the data stored with the fit). Vectors may have either the length of the original data or the number of rows the fit kept.

Details

The conversion takes the standard error as sqrt(vi), so metafor's sampling variance cannot end up in the sebs slot by mistake. Sample sizes are never inferred from the variances; doing so would reintroduce the spurious precision that MAIVE corrects for. They are resolved, in order, from the ni argument, an ni column (or the fit's ni), the ni attribute that escalc() stamps on the effect size column, and finally the exact two-group total n1i + n2i. When none of these is available the function stops and names what it needs.

For rma.uni fits the effect sizes, variances, sample sizes, and any vector supplied through ni or study_id are taken through the same subset and missing-value masks the fit applied, so the rows stay aligned. Multivariate (rma.mv), GLMM (rma.glmm), and other rma subclasses are refused rather than silently flattened.

Value

A data frame with columns bs, sebs, Ns, and, when identifiers were supplied, study_id, ready for maive() or waive().

Examples


dat <- metafor::escalc(
  measure = "SMD",
  m1i = c(2.1, 2.5, 1.9, 2.4, 2.2, 2.6),
  sd1i = c(1.0, 1.2, 0.9, 1.1, 1.0, 1.3),
  n1i = c(40, 50, 30, 45, 60, 35),
  m2i = c(1.8, 2.0, 1.7, 2.1, 1.9, 2.2),
  sd2i = c(1.0, 1.1, 1.0, 1.0, 1.1, 1.2),
  n2i = c(42, 55, 33, 48, 58, 37)
)
maive_dat <- maive_from_metafor(dat)
head(maive_dat)

fit <- metafor::rma(yi, vi, data = dat)
identical(maive_from_metafor(fit), maive_dat)

result <- maive(maive_dat,
  method = 3, weight = 0, instrument = 1,
  studylevel = 0, SE = 0, AR = 0
)


Funnel plot (base graphics)

Description

Components provided: - 'get_funnel_plot()' as the public high-level entrypoint - internal helpers to validate and map '(dat, result)' into plot inputs - an internal base-graphics engine that draws onto the current device

Details

Device management (PNG/SVG/PDF), resolution, and any base64 encoding are the caller's responsibility.


WAIVE: More Aggressive Correction for P-Hacking and Spurious Precision

Description

WAIVE (Weighted Adjusted Instrumental Variable Estimator) provides a more aggressive correction for p-hacking and spurious precision by extending MAIVE with exponential-decay weights that downweight both spuriously precise estimates and extreme outliers.

Usage

waive(
  dat,
  method,
  weight,
  instrument,
  studylevel,
  SE,
  AR,
  first_stage = 0L,
  estimate = NULL,
  se = NULL,
  n = NULL,
  study_id = NULL,
  seed = 123
)

Arguments

dat

Data frame with columns bs, sebs, Ns, study_id (optional). Column names can be remapped with estimate, se, n, and study_id.

method

1 FAT-PET, 2 PEESE, 3 PET-PEESE, 4 EK.

weight

0 no weights, 1 standard weights, 2 MAIVE adjusted weights, 3 study weights.

instrument

1 yes, 0 no.

studylevel

Correlation at study level: 0 none, 1 fixed effects, 2 cluster.

SE

SE estimator: 0 CR0 (Huber-White), 1 CR1 (Standard empirical correction), 2 CR2 (Bias-reduced estimator), 3 wild bootstrap.

AR

Anderson Rubin corrected CI for weak instruments (available for unweighted and MAIVE-adjusted weight versions of PET, PEESE, PET-PEESE, not available for fixed effects): 0 no, 1 yes.

first_stage

First-stage specification for the variance model: 0 levels, 1 log.

estimate

Optional column name to use instead of 'bs'

se

Optional column name to use instead of 'sebs'

n

Optional column name to use instead of 'Ns'

study_id

Optional column name for study identifiers. When not supplied, a column named study_id is used if present; otherwise, if dat has four or more columns, the fourth column is used as the study identifier and a warning names the column. Any fourth column (a moderator, a year) would otherwise drive the study dummies and clustering at every studylevel other than 0, so name the column explicitly or drop it.

seed

Seed for the wild bootstrap when SE = 3. Use NULL to avoid setting a seed (results depend on the current RNG state). Default is 123 for historical reproducibility.

Details

Guided, interactive workflow available at https://www.easymeta.org.

For technical details on WAIVE methodology, see: https://meta-analysis.cz/waive_ottawa.pdf

WAIVE combines variance instrumentation (as in MAIVE) with robust downweighting based on first-stage residuals. Studies with negative residuals (spurious precision) or extreme residuals (outliers) receive exponentially reduced influence in the meta-analytic estimate. This makes WAIVE more aggressive than standard MAIVE at correcting for p-hacking and handling outliers.

Value

List with the same structure as maive(). See ?maive for details.

Examples

dat <- data.frame(
  bs = c(0.5, 0.45, 0.55, 0.6),
  sebs = c(0.25, 0.2, 0.22, 0.27),
  Ns = c(50, 80, 65, 90)
)

result <- waive(dat,
  method = 3, weight = 0, instrument = 1,
  studylevel = 0, SE = 0, AR = 0, first_stage = 0
)