--- title: "Power Enhancement for High-Dimensional Mediation: A Guided Tour" output: rmarkdown::html_vignette: toc: true toc_depth: 2 vignette: > %\VignetteIndexEntry{Power Enhancement for High-Dimensional Mediation: A Guided Tour} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.2) library(POEMED) # Rejection rates quoted in the prose, as percentages. With 40 replications # a rate such as 0.225 falls on a half percent (22.5), so the half is kept # instead of being rounded to a whole number in one direction or the other. pct <- function(rate) format(100 * rate, digits = 3) ``` This vignette is written for a reader who is comfortable with regression but new to high-dimensional mediation. It explains the problem the package solves, builds up the idea behind the power-enhanced tests, then walks through a first analysis, the output, the different outcome types, a simulation study, and finally the real-data application from the article that introduced the tests, Yu and Kelley (in press). You do not need to have read the article first; pointers to it appear where the details live. ## 1. What Is a Mediation Analysis? A mediation analysis asks *how* an exposure affects an outcome. Instead of only asking whether a treatment `X` changes an outcome `Y`, it asks whether `X` works **through** an intermediate variable `M`, the *mediator*. The classic picture is a chain: ``` a b X -----> M -----> Y \ / \________ c' _________/ (direct) ``` The effect of `X` on `Y` that travels through `M` is the **indirect effect**: in a linear model it is the product `a * b` of the `X -> M` path and the `M -> Y` path. The part of `X`'s effect that does not go through `M` is the **direct effect** `c'`. Their sum is the **total effect**. In modern applications there is rarely a single mediator. Genomics studies screen thousands of methylation sites; the application later in this vignette has 57 health-expenditure indicators. When there are many candidate mediators `M = (M_1, ..., M_p)`, the natural first question is simply: > **Is there any active mediator at all?** That is, does `X` affect `Y` > through *any* of the candidate mediators? This is a single global hypothesis test, and it is what POEMED is built to perform with high power. ## 2. The Problem: Total-Indirect-Effect Tests Have a Blind Spot With many mediators, the conventional approach summarizes them by the **total indirect effect**, written `beta`: the sum over all mediators of each one's individual indirect effect. The global test then checks whether `beta = 0`. This works well when the mediators all push the outcome the same way. But consider two active mediators whose individual indirect effects are equal in size and **opposite in sign**: say `+0.5` through `M_1` and `-0.5` through `M_2`. Both mediators are truly active, yet their contributions cancel, so the total indirect effect is ``` beta = (+0.5) + (-0.5) = 0. ``` A test built on `beta` sees zero and concludes "no mediation," even though two mediators are plainly active. This is not a rare edge case: whenever different pathways move an outcome in opposite directions (**heterogeneous** mediation, and in the extreme **contrasting** mediation), the total indirect effect understates the truth and the test loses power. The article calls this out as the core limitation of existing high-dimensional mediation tests. ## 3. The Idea: A Power Enhancement Component The power-enhanced (PE) test fixes the blind spot by adding a second piece that cannot cancel. After a penalized fit narrows the candidates to a small set of mediators, the PE component `J_m` adds up, over those mediators, the **magnitude** of each one's combined path signal. In code notation, with `alpha_hat[j]` the estimated `M -> Y` coefficient of mediator `j`, `Gamma_hat[i, j]` the estimated `X -> M` coefficient from exposure `i`, `se_*` their standard errors, and `p_alpha[j]` and `p_Gamma[i, j]` the two paths' p-values: ``` J_m = sqrt(p) * sum over exposures i and penalized-selected mediators j of |alpha_hat[j] / se_alpha[j]| * |Gamma_hat[i, j] / se_Gamma[i, j]| * 1{max(p_alpha[j], p_Gamma[i, j]) <= error_level / (s * q * log(log(n)))} ``` Here `s` is the number of mediators the penalized fit selected, `q` the number of exposures, and `n` the sample size. This is the default Bonferroni screen; the `"BH"` and `"BY"` methods of Section 6 compare adjusted p-values with `error_level / log(log(n))` instead. Two things matter here. First, the indicator keeps a mediator only when **both** its `X -> M` path and its `M -> Y` path pass that strict, multiplicity-adjusted threshold, so noise mediators do not contribute. The threshold is set by `error_level` (default 0.05), the error rate targeted for the identified mediators, so it shapes the global test as well (Section 6 shows how). Second, because `J_m` sums **absolute values**, a `+0.5` mediator and a `-0.5` mediator *reinforce* each other instead of canceling. The full test statistic is `M_PE = S_n + J_m`, the benchmark Wald statistic `S_n` (the total-indirect-effect test) plus the enhancement. Under the global null of no mediation, the screen keeps no mediator with probability tending to one as `n` grows, so `J_m = 0` and `M_PE` has the same chi-square reference distribution as `S_n` asymptotically. In a finite sample `J_m` is occasionally positive under the null, and because `M_PE` is never smaller than `S_n`, the PE test then rejects a little more often than the benchmark (the simulation in Section 8 shows this). Under heterogeneous alternatives, `J_m` grows large and the test gains power. That is the whole idea: **keep the size in large samples, and add power where the old test is blind.** The same indicator that builds `J_m` also identifies *which* mediators are active: the mediators that pass it are the active mediators a fit reports, its estimate of the truly active set, targeting the familywise error rate (the default) or the false discovery rate. The tuning grid of the penalized fit shapes both the global test and the identified active set; Sections 4, 8, and 11 say how to read it and how to tune it. ## 4. A First Analysis, Step by Step The package can simulate data so you can see the method work before bringing your own. `simulate_mediation_data()` generates the patterns studied in the article. Here is a **contrasting** setting: a few active mediators whose effects cancel to a zero total indirect effect. ```{r sim} set.seed(113) d <- simulate_mediation_data(n = 200, p = 60, outcome = "continuous", pattern = "contrasting", c1 = 1) ``` The result is a list. The four pieces an analysis needs are the exposure, outcome, mediators, and (optionally) confounders: ```{r sim-pieces} dim(d$X) # exposure: 200 observations, 1 column length(d$Y) # outcome: 200 values dim(d$M) # mediators: 200 x 60 d$active_mediators # which mediators are truly active (the ground truth) d$beta # the total indirect effect: zero, up to rounding error ``` So four mediators are truly active, but the total indirect effect is zero because their effects cancel. This is precisely the situation that defeats a total-indirect-effect test. Now run the global test: ```{r first-fit} fit <- pe_mediation(d$X, d$Y, d$M, outcome = "continuous") fit ``` Read the two p-values. `pval_hdmm` is the benchmark Wald test on the total indirect effect; it is large, so that test fails to detect any mediation (exactly the blind spot from Section 2). `pval_pe` is the power-enhanced test; it is essentially zero, so it detects the mediation decisively. The footer lists the active mediators the screen identified, here three of the four truly active mediators. The power enhancement, made concrete. The last footer line reports the tuning parameter `lambda` that the high-dimensional BIC (HBIC) chose for the penalized fit and the grid it searched: by default 100 values from 0.05 to 10, the same grid for every outcome type. HBIC is minimized over the grid alone, so whatever grid is offered, the value chosen is the best of the values offered. Here the smallest value won. The footer says so, and the fit warned, because a minimum at an end of the grid may lie beyond that end or between it and its neighbor; a grid that extends further, or is spaced more finely, is worth a look whenever that happens. Doing that here moves the chosen value inside the grid and leaves the identified active mediators unchanged: ```{r finer-grid} finer <- pe_mediation(d$X, d$Y, d$M, outcome = "continuous", lambda_grid = seq(0.01, 10, length.out = 200)) attr(finer, "tuning")$lambda_selected attr(finer, "active_mediators") ``` The warning on the first fit named a reduced model beside the full one. For a continuous outcome the fit also tunes that reduced model, the outcome on the mediators and any confounders without the exposure, on the same grid; its choice is `lambda_selected_reduced` in the `"tuning"` attribute. The function behind `outcome = "continuous"`, `pe_mediation_linear()`, takes a separate grid for that model as `lambda_grid_reduced` (`pe_mediation()` does not pass one on), which changes that entry and the warning and none of the rows of the table. The grid can be tuned the other way as well: fewer values, or a range narrowed to where the HBIC minimum has been seen to fall, make each fit faster, which matters when many fits are run (Section 8 does this for a simulation study). The chunks below fit on the default grid, and each fit would warn in the same way; the warning is not shown again. ## 5. Reading the Result Table Every POEMED test returns a tidy table that prints with sensible rounding (whole numbers without decimals, p-values to four places) while storing full precision underneath. The rows are: | term | meaning | |---|---| | `stat_hdmm`, `pval_hdmm` | the benchmark Wald statistic `S_n` and its p-value (the total-indirect-effect test of Guo et al.) | | `stat_pe`, `pval_pe` | the power-enhanced statistic `M_PE` and its p-value | | `j_pe` | the power enhancement component `J_m` (the amount added to `S_n`) | | `total_indirect_effect` | the estimated total indirect effect `beta` | | `n_active_mediators` | how many mediators the screen identified as active | | `df` | degrees of freedom of the chi-square reference (the number of exposures) | | `n_candidate_mediators`, `n_observations` | `p` and `n` | The table gives a point estimate of `beta` but no confidence interval, and the article reports none. In simulations, a Wald interval built on the penalized estimate fell short of its nominal coverage, most clearly for binary and count outcomes, so the package does not report one. To pull a number out, index the table like any data frame; the stored value keeps full precision even though the display rounds: ```{r read} fit$value[fit$term == "pval_pe"] # the exact p-value attr(fit, "active_mediators") # indices of the active mediators identified ``` ## 6. Identifying Which Mediators Are Active Which mediators the screen identifies as active depends on the `method` argument. The default, `"Bonferroni"`, targets the familywise error rate and is the most conservative of the three, so it may miss weak mediators. Its control of that rate is asymptotic: in finite samples the rate also depends on the design and on the tuning grid, since a grid that reaches small values of `lambda` lets more candidates into the penalized fit. The `"BH"` and `"BY"` options control the false discovery rate instead and typically recover more mediators. ```{r methods, warning = FALSE} des_idx <- function(f) attr(f, "active_mediators") des_idx(pe_mediation(d$X, d$Y, d$M, outcome = "continuous", method = "Bonferroni")) des_idx(pe_mediation(d$X, d$Y, d$M, outcome = "continuous", method = "BH")) ``` On these data the two methods identify the same three mediators at the default error level; they part ways at a stricter one, shown next. The target error rate is `error_level` (default 0.05): the familywise error rate under `"Bonferroni"`, the false discovery rate under `"BH"` and `"BY"`. It is distinct from the significance level you use to read `pval_pe`, but the global test depends on it as well, because it sets the screening threshold inside `J_m` (Section 3). A stricter value can therefore weaken the enhancement on a given data set, or remove it: ```{r error-level, warning = FALSE} strict <- pe_mediation(d$X, d$Y, d$M, outcome = "continuous", error_level = 0.01) strict[strict$term %in% c("pval_hdmm", "j_pe", "pval_pe"), ] des_idx(pe_mediation(d$X, d$Y, d$M, outcome = "continuous", method = "BH", error_level = 0.01)) ``` On these data the Bonferroni screen at `error_level = 0.01` drops mediator 2, which it identified at the default 0.05, so `J_m` falls from `r format(fit$value[fit$term == "j_pe"], digits = 3)` to `r format(strict$value[strict$term == "j_pe"], digits = 3)`. The test still rejects decisively here, because the two mediators that remain carry a large `J_m`; a level strict enough to leave none would make `J_m` zero and `pval_pe` equal to the benchmark's `pval_hdmm`. At the same level the `"BH"` screen still identifies all three mediators, which is how the false discovery rate methods recover more. ## 7. Binary and Count Outcomes The same construction works for non-continuous outcomes through a link function. Name the outcome type and the front end dispatches to the logistic (binary) or Poisson (count) model. The total indirect effect is then on the link scale (log-odds for binary, log-mean for count). ```{r glm, warning = FALSE} set.seed(113) db <- simulate_mediation_data(n = 250, p = 50, outcome = "binary", pattern = "contrasting", c1 = 1, c2 = 1) pe_mediation(db$X, db$Y, db$M, outcome = "binary") ``` The tuning grid is the same for every outcome type, 100 values from 0.05 to 10, and is tuned the same way (Section 4). ## 8. A Simulation Study: Size and Power `pe_power_curve()` runs Monte Carlo studies of the kind the article reports. It sweeps the signal strength `c1`, simulating many data sets at each value and recording how often each test rejects. At `c1 = 0` (no mediation) the rejection rate estimates the Type I error rate; at nonzero `c1` it estimates power. A rate from `n_rep` replications carries a Monte Carlo standard error of about `sqrt(r * (1 - r) / n_rep)`, so the 40-replication run below knows a rate near 0.05 to within about 0.03 and a rate near 0.5 to within about 0.08. A simulation study is also where the tuning grid is worth tuning to the situation. Each replication searches the whole grid, so the default grid of 100 values costs about five times the fitting of a 20-value grid. The study below passes a shorter grid, 20 values from 0.05 to 2: the fit of Section 4 put the HBIC minimum at the bottom of the default grid, so the shorter grid keeps that end and drops the range above 2, which no fit at this design reaches. Whatever the grid, each fit keeps the best value the grid offers, and the warning a single fit gives when its choice sits at an end of the grid is not raised inside a study, which searches a fixed grid by design. (On these 120 simulated data sets the default grid gives the same six rejection rates; it only takes about five times as long.) ```{r power, fig.alt = "Rejection-rate curves for the benchmark and power-enhanced tests"} set.seed(113) pc <- pe_power_curve(n = 150, p = 50, outcome = "continuous", pattern = "contrasting", c1_grid = c(0, 0.5, 1), n_rep = 40, lambda_grid = seq(0.05, 2, length.out = 20)) pc plot(pc, main = "Contrasting Mediation: PE vs. Benchmark") ``` At `c1 = 0` the benchmark rejects in `r pct(pc$rejection_hdmm[pc$c1 == 0])` percent of replications and the power-enhanced test in `r pct(pc$rejection_pe[pc$c1 == 0])` percent, both near the nominal 5 percent given the Monte Carlo error of 40 replications. The PE rate can never fall below the benchmark's on the same data sets, because `M_PE` is never smaller than `S_n`. It is higher whenever a null replication has a positive `J_m` that carries `M_PE` past the critical value where `S_n` alone falls short (Section 3). As the contrasting signal grows the benchmark rejects in `r pct(pc$rejection_hdmm[pc$c1 == 1])` percent of replications at `c1 = 1` and the power-enhanced test in `r pct(pc$rejection_pe[pc$c1 == 1])` percent. That is the enhancement at work. The article's own study, at `n = 300`, `p = 500`, and 1,000 replications per point, is the converged version of this picture. ## 9. The Real Application: Health Spending as a Mediator The package ships the article's empirical data, `WHO_health_mediation`: a panel of 91 WHO member states over 2000--2021. The exposure is annual growth in GDP per capita, the candidate mediators are 57 health-expenditure indicators from the WHO Global Health Expenditure Database, and there are five health outcomes (infant and under-five mortality, life expectancy, low birthweight, and undernourishment). The substantive question: **does health spending mediate the relationship between economic growth and population health?** ```{r who-data} data(WHO_health_mediation) dim(WHO_health_mediation) WHO_health_mediation[1:3, c("country", "region", "income", "year", "gdp_growth", "imr", "gge_gdp")] ``` The 57 mediators are strongly intercorrelated (many are different normalizations of the same spending), which is exactly the high-dimensional, correlated-mediator regime the method targets. Their definitions are in `WHO_indicator_codebook`: ```{r codebook} head(WHO_indicator_codebook, 4) ``` ### Building One Analysis Design `WHO_mediation_design()` assembles the exposure, outcome, mediator, and confounder matrices for a chosen outcome, handling the missing-data coverage and the confounders (region, income group, and year) for you. The call below follows the preprocessing of the authors' analysis code behind the article's tables: it standardizes the exposure and the mediators, centers the outcome, and leaves the confounders (the region and income indicators and the year) unscaled, then passes `scale = FALSE` so that `pe_mediation()` fits the matrices as given. Its tuning grid, `seq(0.1, 2, length.out = 100)`, is the grid behind the article's real-data tables and the default of `WHO_mediation_analysis()` for the global and every subgroup model. In this global model HBIC picks 0.1, the smallest value of that grid, for the full and the reduced model alike, and one or both sit there in about half of the article's cells; the article's analysis keeps its grid as it is, and so does this vignette, so the warning a single fit gives at an end of its grid is not shown in this section. The article's text says that covariates are standardized before fitting, but its global finding for infant mortality is recovered with the confounders left unscaled. The last part of this section shows what standardizing them as well changes. ```{r who-design, warning = FALSE} des <- WHO_mediation_design("imr") # infant mortality rate c(observations = des$n, mediators = ncol(des$M), confounders = ncol(des$Z)) fit <- pe_mediation(scale(des$X), des$Y - mean(des$Y), scale(des$M), Z = des$Z, outcome = "continuous", scale = FALSE, lambda_grid = seq(0.1, 2, length.out = 100)) identified <- des$indicators[attr(fit, "active_mediators")] WHO_indicator_codebook$description[ match(identified, WHO_indicator_codebook$indicator)] ``` The PE test identifies general government expenditure as a share of GDP (`gge_gdp`) as the mediator through which economic growth reaches infant mortality. Yu and Kelley (in press) report the same single indicator for the global model in their Table 1. ### The Full Subgroup Analysis `WHO_mediation_analysis()` runs the whole set of models the article reports for one outcome (global, then within each WHO region, income group, and region-income cell), prepares the data the same way as the fit above, and returns one row per group, laid out like the article's Table 1 (infant mortality) and Table 2 (undernourishment). Here it fits the global model and the six regions on its default tuning grid. ```{r who-analysis} res <- WHO_mediation_analysis("imr", groupings = c("global", "region")) res[, c("group", "n_countries", "pval_hdmm", "pval_pe", "active_mediators")] ``` Compare the benchmark and PE columns. Where the benchmark test sees nothing (a large `pval_hdmm`) while the PE test rejects decisively and names the indicators responsible, heterogeneous mediation is hiding the signal from the conventional test. In the Western Pacific region, for example, the benchmark p-value is `r format(res$pval_hdmm[res$group == "WPR"], digits = 2)`, yet the PE test rejects and flags compulsory health insurance as a share of current health expenditure (`chi_che`). Table 1 of Yu and Kelley (in press) shows the same contrast for this region. `summary()` reads that comparison off the table for you, counting the groups where the PE test detects mediation the benchmark misses: ```{r who-summary} summary(res) ``` ### Why the Preprocessing Matters Passing the raw design to `pe_mediation()` with the default `scale = TRUE` standardizes the confounders as well, and that is a different model. On the same tuning grid as the first fit: ```{r who-raw, warning = FALSE} raw <- pe_mediation(des$X, des$Y, des$M, Z = des$Z, outcome = "continuous", lambda_grid = seq(0.1, 2, length.out = 100)) c(confounders_unscaled = fit$value[fit$term == "pval_hdmm"], all_standardized = raw$value[raw$term == "pval_hdmm"]) des$indicators[attr(raw, "active_mediators")] ``` The benchmark Wald p-value moves from about `r format(fit$value[fit$term == "pval_hdmm"], digits = 2)` to about `r format(raw$value[raw$term == "pval_hdmm"], digits = 2)`, and the screen identifies a second indicator as active, social health insurance (`shi_che`). Leave the confounders unscaled (or call `WHO_mediation_analysis()`, which does) whenever the goal is to compare results with the article's tables. ## 10. Beyond the Global Test: The Toolkit The global test is the core, but POEMED ships a few conveniences around it. ### A Formula Interface for Data Frames If your variables live in a data frame, `pe_mediate()` takes a formula for the outcome and exposure, the names of the mediator columns, and (optionally) confounder names, and calls `pe_mediation()` for you. ```{r formula, warning = FALSE} set.seed(113) d <- simulate_mediation_data(n = 200, p = 60, outcome = "continuous", pattern = "contrasting", c1 = 1) df <- data.frame(y = d$Y, x = d$X[, 1], d$M) meds <- grep("^X", names(df), value = TRUE) # the mediator columns fit <- pe_mediate(y ~ x, data = df, mediators = meds, outcome = "continuous") ``` ### Why Each Mediator? The Per-Mediator Table `pe_mediators()` opens up the screening step: for every candidate mediator the penalized fit kept, it shows the two path statistics, the screening p-value (the larger of the two path p-values), and whether the screen identified the mediator as active (the `active` column). This is how you see *why* the test reached its conclusion. ```{r mediators} pe_mediators(fit) ``` Mediator 1 is the truly active mediator the screen did not identify: its `M -> Y` statistic is the largest in the table, but its `X -> M` statistic is small, so its screening p-value is large. `plot()` shows the same evidence graphically, the screening strength of each candidate the penalized fit kept, with the mediators the screen identified as active highlighted and the rest marked as screened out. ```{r plot-mediators, fig.alt = "Per-mediator screening evidence for the candidate mediators the penalized fit kept"} plot(fit) ``` ### Working With broom `tidy()` returns the per-mediator table and `glance()` a one-row summary, so a POEMED result drops into broom and tidyverse workflows. ```{r broom} glance(fit) ``` ### All Three Multiplicity Methods at Once Pass `report_all_methods = TRUE` and `pe_selection()` reports the identified active set under Bonferroni (familywise error rate), Benjamini-Hochberg, and Benjamini-Yekutieli (false discovery rate) side by side, as the supplement of the article does. At the default error level the three agree on these data, as in Section 6. ```{r selection, warning = FALSE} fit_all <- pe_mediation(d$X, d$Y, d$M, outcome = "continuous", report_all_methods = TRUE) pe_selection(fit_all) ``` ### Planning the Sample Size `ss_power_pe_mediation()` plans a study: over a grid of candidate sample sizes it estimates the power of the PE test by simulation and stores the smallest sample size that reaches the target power in the `"recommended_n"` attribute. That attribute is `NA` when no size in the grid reaches the target, so choose a grid that brackets it. Under the default tuning grid this contrasting design reaches a power of 0.8 between 100 and 150 observations, so the grid below brackets that. It runs a Monte Carlo study (400 fits on the default grid, about a minute and a half), so it is shown here but not evaluated; a shorter tuning grid, passed as `lambda_grid`, would cut that time. ```{r ssplan, eval = FALSE} plan <- ss_power_pe_mediation(outcome = "continuous", pattern = "contrasting", p = 50, n_grid = c(100, 150, 200, 250), target_power = 0.8, n_rep = 100, seed = 113) plan attr(plan, "recommended_n") ``` Run as shown, it estimates the power of the power-enhanced test at 0.69, 0.92, 1.00, and 1.00 for the four sizes and recommends `n = 150`. Each power estimate from 100 replications carries a Monte Carlo standard error of about 0.04 near a power of 0.8, so a size whose estimate sits just above the target could give way to the next size under another seed; raise `n_rep` for a plan you will report. ## 11. Bringing Your Own Data To analyze your own study, arrange: - `X`: an `n`-by-`q` matrix of exposures (often one column). - `Y`: a length-`n` outcome (continuous, 0/1, or counts). - `M`: an `n`-by-`p` matrix of candidate mediators (`p` may exceed `n`). - `Z` (optional): an `n`-by-`d` matrix of confounders. then call `pe_mediation(X, Y, M, Z, outcome = ...)`. The defaults standardize the inputs as the method assumes, choose the tuning parameter by a high-dimensional information criterion over a grid of 100 values from 0.05 to 10 for every outcome type, and target the familywise error rate when identifying individual active mediators. The grid can be tuned: shortened or narrowed to save time, widened or refined when the value chosen sits at an end of the grid, which the fit warns about and the footer notes (Section 4). Everything returned is an ordinary data frame you can index, save, or plot, and the print footer reports the tuning parameter chosen and the grid it came from. ### When POEMED Is the Right Tool, and When It Is Not The tests assume a linear (or generalized linear) outcome model with a sparse set of active mediators, standardized inputs, and complete data. The section "When to Use POEMED" of `?pe_mediation` states the practical limits seen on simulated data. In brief: - Sample size. The penalized selection needs `n` large relative to `log(p)` and to the signal. When it is not, as at `n = 100` with `p = 2000` under the contrasting pattern, the penalized fit selects very few candidates, usually one, and the test has little left to draw on. - Strongly correlated mediators. Correlation among the mediators weakens both the penalized selection and the screen: the screen can come up empty, and the identified active set varies from sample to sample. An autoregressive correlation of 0.9 among neighboring mediators was enough to empty the screen in a design where 0.5 was not. - Active mediators identified in finite samples. The screen's control of its error rate is asymptotic, so the identified active set can hold a mediator that is not truly active. The rate depends on the design and on the tuning grid, and a grid that lowers it can do so at the cost of recall. - Rare binary outcomes. With only a few percent events the penalized logistic fit that HBIC chooses is empty, and the function says so. - Overdispersed counts. The count model is Poisson. Under negative binomial counts its size held up, but a share of the fits came back empty. - Missing values. `pe_mediation()` stops on a missing value, so supply complete cases; `pe_mediate()` drops incomplete rows and says how many it dropped. ## References Yu, X., & Kelley, K. (in press). Power Enhancement in High-Dimensional Heterogeneous Mediation Analysis. *Journal of the American Statistical Association*. Fan, J., Liao, Y., & Yao, J. (2015). Power enhancement in high-dimensional cross-sectional tests. *Econometrica, 83*(4), 1497--1541. https://doi.org/10.3982/ECTA12749 Guo, X., Li, R., Liu, J., & Zeng, M. (2022). High-dimensional mediation analysis for selecting DNA methylation loci mediating childhood trauma and cortisol stress reactivity. *Journal of the American Statistical Association, 117*(539), 1110--1121. https://doi.org/10.1080/01621459.2022.2053136 ## Session Information ```{r session-info} sessionInfo() ```