MAIVE corrects meta-analyses for publication bias and for many forms of p-hacking. Besides effect and standard error, it also asks for sample size.
You will need: effect · se ·
n_obs · study_id (the latter is needed when a study reports
several estimates, and inference then clusters on it)
Open EasyMeta Download the example data (CSV)
Or hand it to an AI assistant. Attach your spreadsheet and say:
Run MAIVE on this dataset, following the protocol at
https://meta-analysis.cz/maive/how-to/#ai. If your assistant cannot read links, open
the protocol block at the foot of this page and paste the protocol
instead.
Worked example: do hedge funds earn alpha?
75 estimates from 9 studies, restricted in this tutorial to asset-based-style models (the ones that price a fund against benchmarks you can trade) estimated on cross-sectional data. The mean reported alpha is 0.33% per month.

Reading the funnel. Each hollow point is a reported estimate plotted against its standard error, so the most precise estimates sit at the top. The filled points are the same estimates carrying the standard error MAIVE fits from sample size instead of the reported one, and the solid line is MAIVE's fit through them. It is straight because the PET-PEESE rule picks PET when the intercept is not significant, as here, and the PEESE quadratic when it is.
MAIVE: 0.047% per month (SE 0.096).
First-stage F: 128.3. Settings: PET-PEESE, log first stage,
equal weights, wild bootstrap clustered by study.
Reading the output, as EasyMeta reports it:
- Bias test. The Egger test rejects funnel symmetry (p = 0.002): the less precise an estimate, the larger the alpha it reports.
- Spurious precision. The Hausman statistic is 0.79 against a critical value of 3.84: MAIVE and plain PET-PEESE agree here, so the test does not detect inflated precision, and the correction comes from the funnel asymmetry.
- Corrected effect. 0.047% per month against a reported 0.33%. Corrected, the alpha is gone.
Shrinking the plain PET-PEESE estimate further is the usual outcome. In the paper, across 267 meta-analyses with a first-stage F above 10, MAIVE landed closer to zero than PET-PEESE in 67% of them, and in 75% of those where PET-PEESE was significant.
If the first stage is weak
Below an F of 10, report the Anderson-Rubin interval instead of the point estimate. In the euro-trade dataset (61 estimates) F is 0.24; MAIVE gives -0.55 (SE 0.81), and the AR interval is [-1.90, 0.79], so the corrected effect is only weakly identified. RTMA, by Mathur, rests on different assumptions and is the cross-check to run when the first stage is this weak. EasyMeta runs it too.
If you suspect serious p-hacking
In the female directors and ESG ratings dataset (533 estimates from 106 studies, mean 0.28 rating points), 44 estimates sit just above |z| = 1.96 and 33 just below, in windows 0.5 wide. Bunching like that is what selective reporting leaves behind.
WAIVE, an experimental option in EasyMeta, is the more aggressive correction: it additionally downweights estimates that look too precise for their sample size. MAIVE gives 0.185 (SE 0.036), WAIVE 0.143 (SE 0.089). MAIVE still finds an effect here; WAIVE does not.
The same run in R
EasyMeta runs the MAIVE package. These arguments are the settings above, and they return the same numbers to every digit printed on this page.
install.packages("MAIVE")
library(MAIVE)
d <- read.csv("https://meta-analysis.cz/maive/how-to/alpha.csv")
dat <- data.frame(bs = d$effect, sebs = d$se,
Ns = d$n_obs, study_id = d$study_id)
fit <- maive(dat,
method = 3, # PET-PEESE
weight = 0, # equal weights
instrument = 1, # MAIVE; 0 gives plain PET-PEESE
studylevel = 2, # cluster by study
SE = 3, # wild bootstrap
AR = 1, # Anderson-Rubin interval
first_stage = 1) # log first stage; package defaults to levels
fit$beta # corrected estimate, and fit$SE its standard error
fit$SE_instrumented # one corrected standard error per estimate
Corrected standard errors for any estimator
You do not have to run a meta-regression to use MAIVE. Both the app and the package
return the fitted standard error of every estimate, seInstrumented in the API
response and SE_instrumented in R. Use those in place of the reported ones and
run whatever you would have run anyway: random effects, a selection model, anything that
takes a standard error. The p-hacking that operates through reported precision is corrected
before your estimator ever sees the data.
For AI assistants and code
POST https://api.maive.eu/v1/run-model
{
"data": [
{"effect": 0.49, "se": 0.2438, "n_obs": 152, "study_id": "1"},
{"effect": 0.89, "se": 0.7236, "n_obs": 33, "study_id": "1"},
{"effect": 0.93, "se": 0.7381, "n_obs": 18, "study_id": "1"},
{"effect": 0.46, "se": 0.1575, "n_obs": 81, "study_id": "1"},
{"effect": 0.04, "se": 0.2, "n_obs": 20, "study_id": "1"},
{"effect": 0.0658, "se": 0.0383, "n_obs": 136, "study_id": "20"}
],
"parameters": {
"modelType": "MAIVE", "maiveMethod": "PET-PEESE", "weight": "equal_weights",
"useLogFirstStage": true,
"standardErrorTreatment": "bootstrap", "includeStudyClustering": true,
"computeAndersonRubin": true, "winsorize": 0
}
}
Those are the first six of the 75 rows in alpha.csv; send all of them to get the numbers above.
Full protocol, if your assistant cannot read links:
Run MAIVE on my data via the EasyMeta API (POST api.maive.eu/v1/run-model).
Send "data" as row objects with effect, se, and n_obs. n_obs is the total
sample size behind the estimate, not degrees of freedom; never guess it or
back it out of the standard error. Add study_id only where several estimates
come from one primary study: never invent it, and ask if the grouping is
unclear. Giving every row its own study_id is rejected.
Nest exactly this under "parameters":
{"modelType": "MAIVE", "maiveMethod": "PET-PEESE", "weight": "equal_weights",
"useLogFirstStage": true, "standardErrorTreatment": "bootstrap",
"includeStudyClustering": true, "computeAndersonRubin": true, "winsorize": 0}.
Top-level settings are silently ignored. Use the synchronous endpoint.
includeStudyClustering is what clusters; dropping it changes the standard
errors and the F without any error. Check firstStage.mode is "log" in the
response; anything else means the settings did not take effect.
Read effectEstimate, standardError, firstStageFStatistic, publicationBias,
hausmanTest, andersonRubinCI, and seInstrumented from the response, and compute
the simple mean from the effects you sent. Report the corrected estimate
against that mean, the first-stage F, the Egger and Hausman tests, and the
Anderson-Rubin interval whenever F < 10, in place of the point estimate.
Report any warnings verbatim. If you cannot issue the request, say so and tell
the user to upload their spreadsheet at easymeta.org. For R users, hand them
this rather than R from memory:
library(MAIVE)
fit <- maive(data.frame(bs = effect, sebs = se, Ns = n_obs, study_id),
method = 3, weight = 0, instrument = 1, studylevel = 2,
SE = 3, AR = 1, first_stage = 1)
With no grouping, drop study_id from the data.frame and set studylevel = 0.
Never report numbers you did not receive or compute from the data you sent.
MAIVE is not tied to PET-PEESE. EasyMeta will apply the same correction to PET, PEESE, or the endogenous kink model, and it also runs weighted least squares and RTMA.
Computed with EasyMeta on meta-analysis.cz data v1.1.1, 2026-08-25; every request and response archived in maive-howto.json. The settings on this page are the specification we recommend as authors of MAIVE. It is newer than the 2025 Nature Communications paper: the log first stage now replaces the levels baseline used there.