Skip to contents

mars includes several workflows that start from different research-synthesis questions. This vignette is a map of those workflows: what each one is for, which data shape it expects, which function usually comes first, and where to go next for a full example.

library(mars)

Start with the Research Question

The table below is a quick guide. Many analyses begin with mars(), but the best entry point depends on whether the synthesis is about a single effect, dependent effects, methodology adjustment, networks, or post-synthesis reporting.

If your goal is… Start with… Main data shape Full vignette
Estimate an average effect or meta-regression mars() One row per effect size vignette("MARS-Model-Examples", package = "mars")
Model nested or dependent effects mars() Multiple effects per study, cluster, or outcome vignette("MARS-Model-Examples", package = "mars")
Build within-study covariance matrices mars() with the appropriate varcov_type Effect sizes plus sample-size/design inputs vignette("Within-Study-VarCov-Metrics", package = "mars")
Select among many moderators with penalization mars(..., lasso = TRUE) Effect sizes with candidate moderator columns ?mars and package examples
Separate methodology and substantive moderators masmr() Effect sizes with methodology and substantive covariates vignette("MASMR-Workflow", package = "mars")
Handle missing moderator values before fitting mars(..., missing = "em") Effect-size data with partially observed moderator columns vignette("Moderator-Missing-Data-EM", package = "mars")
Model heterogeneity as a function of study features mars(..., scale_formula = ...) Effect sizes plus scale-side predictors vignette("Scale-Location-Models", package = "mars")
Fit a path model after correlation synthesis mars() then path_model() Study-level correlation columns vignette("Latent-Factor-After-Correlation-Synthesis", package = "mars")
Synthesize mixed moderator/outcome correlations mixed_corr_meta() then path_model() Individual effect-size rows with moderators vignette("Mixed-Correlation-Path-Workflow", package = "mars")
Produce a standardized synthesis report synthesis_factor_report() A fitted correlation-synthesis model vignette("Synthesis-Factor-Report-Workflow", package = "mars")
Diagnose model residuals or influential cases residual_diagnostics() and influence_diagnostics() A fitted mars model vignette("Residual-Diagnostics-Workflow", package = "mars")
Compare bootstrap, jackknife, or permutation estimates mars_alt_estimation() A fitted-model specification passed through resampling wrappers vignette("Alternative-Estimation-Frameworks", package = "mars")
Assess publication bias publication_bias() A fitted mars model vignette("Publication-Bias-Models", package = "mars")
Estimate treatment networks network_meta() Contrast-level treatment-comparison data vignette("Network-Meta-Analysis", package = "mars")
Explore nonlinear moderator patterns mars_rf() Meta-analytic data with candidate predictors vignette("Random-Forest-Meta-Analysis", package = "mars")
Build review graphics risk_of_bias_plot(), gap_map_plot(), or prisma_diagram() Review-coding data Plot-specific vignettes

Core Model Fitting with mars()

Use mars() when the primary task is estimating an average effect, fitting a meta-regression, or modeling dependent effect sizes. The three most common structures are univariate, multivariate, and multilevel.

# One effect size per study
fit_uni <- mars(
  data = bcg,
  formula = yi ~ 1 + ablat,
  studyID = "trial",
  variance = "vi",
  varcov_type = "univariate",
  structure = "univariate"
)

# Correlation synthesis from study-level correlation columns
fit_cor <- mars(
  data = becker09,
  studyID = "ID",
  effectID = "numID",
  sample_size = "N",
  effectsize_type = "cor",
  varcov_type = "weighted",
  variable_names = c(
    "Cognitive_Performance",
    "Somatic_Performance",
    "Selfconfidence_Performance",
    "Somatic_Cognitive",
    "Selfconfidence_Cognitive",
    "Selfconfidence_Somatic"
  )
)

# Nested effect sizes
fit_ml <- mars(
  data = school,
  formula = effect ~ 1 + (1 | district/study),
  studyID = "district",
  variance = "var",
  varcov_type = "multilevel",
  structure = "multilevel"
)

Choose this path first when the estimand itself is the main deliverable. After fitting, common next steps are summary(), diagnostics, profile likelihoods, alternative estimation, publication-bias checks, and reporting.

LASSO Moderator Selection

Use lasso = TRUE inside mars() when there are many candidate fixed-effect moderators and you want a penalized exploratory screen before fitting a smaller confirmatory model. LASSO is most useful when the moderator set is larger than you would comfortably interpret in an ordinary meta-regression.

fit_lasso <- mars(
  data = teacher_expectancy,
  formula = yi ~ 1 + year + weeks + factor(setting) + factor(tester),
  studyID = "study",
  variance = "vi",
  varcov_type = "univariate",
  structure = "univariate",
  estimation_method = "MLE",
  lasso = TRUE
)

summary(fit_lasso)

Use the selected terms as candidates for a transparent follow-up model with lasso = FALSE.

Methodology-Adjusted Meta-Regression

Use masmr() when methodology variables may explain systematic variation that you want to separate from substantive predictors. This is a two-stage workflow: stage 1 adjusts for methodology moderators, and stage 2 models the adjusted effects with substantive moderators.

fit_masmr <- masmr(
  data = teacher_expectancy,
  methodology_mods = c("factor(tester)"),
  substantive_mods = c("year", "weeks", "factor(setting)"),
  formula = yi ~ 1 + year + weeks + factor(setting) + factor(tester),
  studyID = "study",
  variance = "vi",
  varcov_type = "univariate",
  structure = "univariate"
)

summary(fit_masmr)

This path is most useful when the question is not only “what predicts the effect?” but also “does the substantive relationship remain after accounting for study-method features?”

Missing Moderator Data

Use missing = "em" when moderator columns contain missing values and the analysis should impute missing moderator information before fitting the meta-regression. This option is intended for moderator missingness; it does not replace careful handling of missing effect sizes, variances, or study IDs.

fit_missing <- mars(
  data = school,
  formula = effect ~ 1 + year + (1 | district/study),
  studyID = "district",
  variance = "var",
  varcov_type = "multilevel",
  structure = "multilevel",
  missing = "em"
)

summary(fit_missing)

The dedicated missing-data vignette shows univariate, multilevel, and multivariate examples.

Scale-Location Models

Use scale-location models when the between-study heterogeneity, not only the mean effect, may vary with study features. In mars(), the location model is specified with formula, and the scale side is specified with scale_formula.

fit_scale <- mars(
  data = school,
  formula = effect ~ 1 + year + (1 | district/study),
  scale_formula = ~ year,
  studyID = "district",
  variance = "var",
  varcov_type = "multilevel",
  structure = "multilevel"
)

summary(fit_scale)

This path is useful when heterogeneity itself is substantively meaningful, for example when older and newer studies may differ in residual dispersion.

Correlation Synthesis to Path or Factor Models

When studies report correlation matrices, a common workflow is to synthesize the correlations first and then fit a path, EFA, or CFA model to the pooled correlation matrix.

fit_cor <- mars(
  data = becker09,
  studyID = "ID",
  effectID = "numID",
  sample_size = "N",
  effectsize_type = "cor",
  varcov_type = "weighted",
  variable_names = c(
    "Cognitive_Performance",
    "Somatic_Performance",
    "Selfconfidence_Performance",
    "Somatic_Cognitive",
    "Selfconfidence_Cognitive",
    "Selfconfidence_Somatic"
  )
)

path_fit <- path_model(
  fit_cor,
  "Performance ~ Cognitive + Somatic + Selfconfidence"
)

summary(path_fit)

For direct latent-variable workflows, use efa_from_synthesis() or cfa_from_synthesis(). For manuscript-oriented output, use synthesis_factor_report() after the correlation synthesis model.

Mixed Correlations for Moderator Path Models

Use mixed_corr_meta() when the path model combines an effect-size outcome with moderator variables from a long effect-size dataset. This differs from the correlation-synthesis workflow above because the moderator correlations are estimated from the meta-analytic rows rather than read from reported correlation matrices.

corr_fit <- mixed_corr_meta(
  data = teacher_expectancy,
  outcome = "yi",
  variance = "vi",
  moderators = c("year", "weeks", "setting", "tester")
)

path_fit <- path_model(
  corr_fit,
  "yi ~ year + weeks + setting + tester",
  num_obs = nrow(teacher_expectancy)
)

This path is exploratory and useful for building a correlation-style summary of relationships among an effect-size outcome and coded study features.

Diagnostics, Bias, and Sensitivity Workflows

After fitting a model with mars(), move to diagnostics when the next question is about robustness, influential cases, or model adequacy.

fit <- mars(
  data = bcg,
  formula = yi ~ 1 + ablat,
  studyID = "trial",
  variance = "vi",
  varcov_type = "univariate",
  structure = "univariate"
)

residual_diagnostics(fit)
influence_diagnostics(fit)
profile_random_effects(fit)

bias_fit <- publication_bias(fit)
summary(bias_fit)

For resampling-oriented sensitivity checks, see bootstrap_mars(), replicate_bootstrap(), sample_jackknife(), replicate_jackknife(), permutation_mars(), and mars_alt_estimation().

Alternative Estimation Frameworks

Use the alternative-estimation helpers when the main question is how stable the estimated coefficients are under bootstrap resampling, leave-one-study-out jackknife replication, or permutation. These workflows refit the model many times, so start with small examples and increase replication counts only after the model specification is settled.

alt_fit <- mars_alt_estimation(
  type = "bootstrap",
  number_bootstraps = 100,
  data = school,
  formula = effect ~ 1 + (1 | district/study),
  studyID = "district",
  variance = "var",
  varcov_type = "multilevel",
  structure = "multilevel"
)

summary(alt_fit)

Network Meta-analysis

Use network_meta() when the data are treatment contrasts and the question is about direct, indirect, and total treatment effects. Network workflows usually start from contrast-level data with one row per observed comparison.

nma_fit <- network_meta(
  data = contrast_data,
  study_id = "study",
  treatment_1 = "t1",
  treatment_2 = "t2",
  effect = "yi",
  variance = "vi",
  reference = "control"
)

summary(nma_fit)
network_league_table(nma_fit)
network_forest_plot(nma_fit)

Use network_pairwise_data() first when your source data are arm-level rather than contrast-level.

Exploratory Random-Forest Meta-analysis

Use mars_rf() when the question is exploratory moderator detection or prediction rather than confirmatory likelihood-based estimation. The random forest workflow supports univariate, multivariate, and multilevel data shapes, but the output should be interpreted as exploratory.

rf_fit <- mars_rf(
  data = teacher_expectancy,
  formula = yi ~ year + weeks + factor(setting) + factor(tester),
  studyID = "study",
  variance = "vi",
  varcov_type = "univariate",
  structure = "univariate",
  num_trees = 25,
  seed = 123
)

summary(rf_fit)
rf_importance(rf_fit)

Use mars() after this step for a confirmatory model if the forest suggests a moderator pattern worth estimating directly.

Reporting and Review Graphics

Some workflows are about communicating a synthesis rather than fitting the main statistical model.

Use synthesis_factor_report() when the analysis starts from a fitted correlation-synthesis model and the goal is a standardized object containing pooled correlations, uncertainty, latent-factor results, diagnostics, tables, plots, and reproducibility notes.

Use risk_of_bias_plot(), gap_map_plot(), and prisma_diagram() for review process graphics. These functions do not require a fitted mars model; they work from review-coding or flow-count data.

A Practical Order of Operations

For many projects, a useful analysis order is:

  1. Fit the primary synthesis with mars(), masmr(), or network_meta().
  2. Check residuals, influence, and profile likelihoods for the fitted model.
  3. Add sensitivity checks, publication-bias models, or alternative estimation only when they answer a specific robustness question.
  4. For correlation syntheses, move from pooled correlations to path, EFA, CFA, or synthesis_factor_report().
  5. Use review graphics and report exporters after the statistical target is clear.

This order is not mandatory, but it keeps the main estimand visible while the supporting workflows add interpretation, robustness, and communication.