sample_size_EGA_montecarlo: A Priori Sample Size Estimation for EGA Using Monte Carlo...

View source: R/sample_size_EGA_montecarlo.R

sample_size_EGA_montecarloR Documentation

A Priori Sample Size Estimation for EGA Using Monte Carlo Simulation

Description

Estimates an a priori sample size for psychometric network designs using Monte Carlo simulation. Data are generated from a population correlation matrix or from a hypothesized partial correlation network, then EGAnet::EGA() is fitted across candidate sample sizes.

When the input is a correlation matrix, the implied partial correlation network is computed and used as the ground truth for edge-recovery metrics (since EGAnet::EGA() returns a partial correlation network).

Optionally runs in parallel using future.apply with a per-replication progress bar via progressr.

Usage

sample_size_EGA_montecarlo(
  community_sizes = NULL,
  within_edge = 0.1,
  bridges = NULL,
  community_names = NULL,
  population_network = NULL,
  communities = NULL,
  sample_sizes = c(150, 250, 400, 600, 900, 1300),
  n_rep = 500,
  network_type = c("partial", "correlation"),
  data_type = c("ordinal", "continuous"),
  power_target = 0.8,
  validation_n_rep = 0,
  sensitivity = FALSE,
  plots = FALSE,
  output_dir = NULL,
  parallel = FALSE,
  n_workers = NULL,
  seed = NULL,
  verbose = TRUE,
  control = list(),
  ...
)

Arguments

community_sizes

Integer vector with the number of items per community (e.g. c(4, 4, 4, 4) for a 4-community scale with 4 items each). When set, the function builds the population partial- correlation network and the community assignment internally; population_network and communities can be left at NULL. This is the recommended simple API.

within_edge

Partial-correlation weight assigned to every within- community edge when the network is built internally. Default 0.10 (a realistic, weak-loading scenario consistent with Christensen et al., 2024). Ignored if population_network is supplied.

bridges

Optional data.frame (or matrix coercible to one) with columns i, j, weight describing inter-community bridge edges (1-based item indices). Default NULL = no bridges.

community_names

Optional character vector of community labels used when building communities internally. Default NULL = c("F1", "F2", ...).

population_network

Optional square matrix supplied directly (advanced API): either the population correlation matrix (network_type = "correlation") or the hypothesized partial correlation network (network_type = "partial"). When provided, communities must also be provided and factor_sizes is ignored.

communities

Expected community assignment when using the advanced API. Either a named list of item indices per dimension or a vector with one community label per item.

sample_sizes

Numeric vector with candidate sample sizes. Default c(150, 250, 400, 600, 900, 1300) brackets the typical EGA range reported in the literature (Christensen, Garrido, Guerra-Pena & Golino, 2024; Golino et al., 2020).

n_rep

Number of Monte Carlo replications per sample size. Default 500 (500-1000 is the working range used in published EGA simulations).

network_type

"partial" (default, recommended) or "correlation".

data_type

"ordinal" (default, the standard in psychometric scales) or "continuous".

power_target

Numeric in (0, 1). Target probability for the combined power curve. Default 0.80 (Cohen-style convention).

validation_n_rep

Number of additional replications at the recommended n for empirical power validation. Set to 0 (default) to skip; 500 is a good value when reporting in a paper.

sensitivity

Logical. If TRUE the function automatically runs a sensitivity sweep over the most influential arbitrary choices of the pipeline: true_edge_threshold (0.01 / 0.05 / 0.10), edge_threshold_method ("absolute" vs "match_true"), combination ("and" vs "primary") and, for ordinal data, a floor pattern of thresholds. The two edge-threshold sweeps only run when a target depends on the edge thresholds (sensitivity, specificity, precision, fdr, edge_correlation_true_edges or mae_true_edges). Each row is compared with the recommendation of the main run. Results are stored in $sensitivity. Default FALSE.

plots

Logical. If TRUE, generates the standard plots (plot_power_curve_ci, plot_failure_decomposition, plot_sample_size_EGA_montecarlo and the bootstrap distribution of n*). Plots are stored in $plots and saved to disk if output_dir is set. Default FALSE.

output_dir

Optional path to a directory. When set, the function creates the directory if needed and writes result.rds, summary.csv, sensitivity.csv (if applicable) and PNGs of all plots. Default NULL (no files written).

parallel

Logical; run replications in parallel via future.apply::future_lapply(). Default FALSE.

n_workers

Optional integer with the number of parallel workers when parallel = TRUE. Default min(8L, future::availableCores() - 1L). The cap at 8 is deliberate: on Windows each future::multisession worker spawns a fresh Rscript that re-loads EGAnet (~400 MB RAM and several seconds of startup each). Going wider routinely freezes the user-visible progress bar at "0-7%" while the workers initialise. Override explicitly (e.g. n_workers = 11 on a 12-core box) if you have ~5 GB of free RAM and want the extra throughput.

seed

Optional random seed. With parallel = TRUE the seed is forwarded to future.seed for reproducible parallel RNG.

verbose

Logical; print progress messages and show a progress bar.

control

Optional named list to override advanced defaults. See sample_size_EGA_control for the full list of tunable parameters and their literature-backed defaults (categories, corr, model, algorithm, uni.method, criteria, targets, recommendation_method, boots, require_convergence, require_correct_dimensions, combination, primary_metric, true_edge_threshold, estimated_edge_threshold, edge_threshold_method, thresholds).

...

Additional arguments passed to EGAnet::EGA().

Value

A list with class sample_size_EGA_montecarlo containing the recommended sample size, summary table (with median, mean, 95 percent Monte Carlo bands and per-metric power curves), raw replication results, criteria, targets, isotonic interpolation, bootstrap distribution and CI for the recommended n, validation results (when requested), the population correlation matrix, the true partial-correlation network used as ground truth, and the expected communities.

Bootstrap interpretation

The 95 percent CI returned in recommended_n_ci (and the band available via plot_power_curve_ci()) captures Monte Carlo uncertainty of the recommended-n estimator conditional on the assumed population model and the chosen pipeline. It is a within-model uncertainty band, not a population-level inferential statement. In particular, it does NOT account for: (1) misspecification of population_network (the wrong "truth"); (2) departures from the simulated data-generating process such as real ordinal scales with floor / ceiling effects, missingness, or non-normality; or (3) differences between the chosen EGA pipeline (corr, model, algorithm) and what users will actually run on their data.

For robust reporting, complement the CI with sensitivity analyses: vary the population network (denser or sparser), edge_threshold_method, combination, true_edge_threshold (e.g. 0.01 vs 0.05 vs 0.10, usually the most influential arbitrary choice in the pipeline when the targets include edge-recovery metrics), and thresholds (use make_likert_thresholds() to build floor / ceiling patterns). The validation list provides an empirical check that the recommended n actually delivers the target power on a fresh batch of replications.

Partial-to-Sigma convention

When network_type = "partial", the implied population correlation matrix Sigma is reconstructed from the partial-correlation network P by setting the precision matrix to K = I - P (unit residual variances on the diagonal, off-diagonal -P), inverting to obtain a covariance, and rescaling to a correlation. This is one valid parameterisation but not the only one: different residual-variance choices are compatible with the same partial structure and produce different Sigma, different simulated data, and ultimately different recommended_n values. The recommendation is therefore conditional on this generative convention. Report it explicitly in the manuscript and, if the partial network admits a natural alternative scaling, run a sensitivity analysis under that alternative.

Edge-recovery metrics under network_type = "correlation"

When network_type = "correlation" the implied true partial network is computed by inverting Sigma and is typically dense. Because model = "glasso" produces sparse estimates, binary edge-recovery metrics (sensitivity, specificity, precision, fdr) become structurally biased regardless of sample size: the design itself imposes a sparsity mismatch. In this regime, prefer targets based on ari (community recovery) or edge_correlation (continuous agreement) and treat binary edge targets as untrustworthy. The function emits a warning if you combine network_type = "correlation" with binary edge metrics in targets.

Examples

# A toy run: two communities of four items, three candidate sample sizes
# and 10 replications each. Real studies need n_rep = 500 or more.
res <- sample_size_EGA_montecarlo(
  community_sizes = c(4, 4),
  within_edge = 0.20,
  sample_sizes = c(100, 200, 400),
  n_rep = 10,
  data_type = "continuous",
  seed = 1,
  verbose = FALSE,
  control = list(boots = 100, corr = "pearson", algorithm = "walktrap")
)
res
res$summary[, c("Sample_Size", "power_combined")]

InterconectaR documentation built on Oct. 16, 2026, 1:06 a.m.