GAM-based covariate pre-screening

Description

Screens all declared covariates against each ETA using independent generalised additive model (GAM) regressions. For each ETA x covariate pair the function fits eta ~ f(cov) and reports the AIC improvement over the null model eta ~ 1. Covariates are ranked by delta_aic = AIC_null - AIC_best; a positive value means the covariate improves the null model for that ETA.

Usage

ferx_gam_screen(
  fit,
  etas = NULL,
  covariates = NULL,
  spline_df = c(2L, 3L),
  include_linear = TRUE,
  shrinkage_warn = 0.3
)

Arguments

  • fit: A ferx_fit object with fit$ebe_etas and fit$covtab populated (the model must declare a [covariates] block).
  • etas: Character vector of ETA names to screen. NULL (default) screens all ETAs present in fit$ebe_etas.
  • covariates: Character vector of covariate names to screen. NULL (default) uses all covariates declared in fit$covariate_types (or inferred from fit$covtab).
  • spline_df: Integer vector of natural-spline degrees of freedom to try for continuous covariates. Default c(2L, 3L) matches Xpose4’s defaults.
  • include_linear: Logical. Include the linear form as a candidate. Default TRUE.
  • shrinkage_warn: Numeric fraction in [0, 1]. Warn when an ETA’s shrinkage (from fit$shrinkage_eta) exceeds this threshold. Default 0.30.

Details

This is the R equivalent of Xpose4’s xpose.gam() (Jonsson and Karlsson, Pharm Res 1999). Like Xpose4, it uses independent regressions (not stepwise backfitting), which is appropriate for a pre-screening role where speed and interpretability matter most. The functional form candidates for continuous covariates are:

  • Linear: eta ~ 1 + x
  • Natural cubic spline: eta ~ 1 + ns(x, df) for each df in spline_df (when n > df + 1)

For categorical covariates: one-hot encoding with the lowest observed level as the reference. All numerical computation (OLS, AIC, spline basis construction) is performed in Rust via ferx_rust_gam_screen(). This wrapper handles input validation, per-subject covariate aggregation, and result formatting. The AIC formula used is n * log(RSS/n) + 2*p, which gives the same delta_aic as R’s AIC(lm()) and Xpose4’s gam::gam().

Shrinkage caveat

EBE-based covariate screening is only informative when ETA shrinkage is low (< 30between the estimated ETA and a covariate is attenuated. A warning is emitted for each ETA whose shrinkage exceeds shrinkage_warn.

Seealso

Other diagnostics: [check_diagnostics](check_diagnostics.qmd), [check_strictness](check_strictness.qmd), [ferx_bic](ferx_bic.qmd), [ferx_conddist](ferx_conddist.qmd), [ferx_cov_screen](ferx_cov_screen.qmd), [ferx_get_warnings](ferx_get_warnings.qmd), [ferx_runlog_iters](ferx_runlog_iters.qmd), [ferx_trace](ferx_trace.qmd), [plot.ferx_bootstrap](plot.ferx_bootstrap.qmd), [plot.ferx_fit](plot.ferx_fit.qmd), [summary.ferx_fit](summary.ferx_fit.qmd)

Concept

diagnostics

Value

A data frame (returned invisibly; also printed) with one row per ETA x covariate pair and columns:

  • eta_name: ETA name (e.g. "ETA_CL").
  • covariate: Covariate name.
  • delta_aic: AIC_null - AIC_best. Positive means the covariate improves the null model.
  • best_form: Winning functional form: "Linear", "Spline(df=2)", "Spline(df=3)", or "Categorical".
  • aic: AIC of the best model.
  • aic_null: AIC of the null (intercept-only) model.
  • r_squared: R-squared of the best model.
  • shrinkage: ETA shrinkage from the fit (fraction).

Returns NULL with a message when the fit has no ETA or covariate data. Returns an empty data frame when no pairs can be screened.

Examples

ex  <- ferx_example("two_cpt_oral_cov")
fit <- ferx_fit(ex$model, ex$data, method = "focei", covariance = FALSE)
ferx_gam_screen(fit)