Function for biomarker score with confounder-adjusted risk model
Usage
adjust_score(
data_set,
biomarker,
outcome,
confounders = NULL,
k = 2,
maxit = 1000,
epsilon = 1e-08,
CompCase = FALSE,
xgb_params = NULL,
validate = FALSE,
test_size = 0.2,
seed = 123
)Arguments
- data_set
Data frame containing biomarker, outcome, and confounders.
- biomarker
Character, name of biomarker column.
- outcome
Character, name of binary outcome column (0/1).
- confounders
Character vector of confounder column names (default = NULL).
- k
Integer, number of mixture components (default = 2).
- maxit
Integer, maximum EM iterations.
- epsilon
Numeric, convergence tolerance for EM.
- CompCase
Logical, whether to perform complete case analysis (default = FALSE).
- xgb_params
Optional list of hyperparameters passed to
xgboost::xgb.train. Can override default settings such asmax_depth = 3,eta = 0.05,subsample = 0.8, andcolsample_bytree = 0.8.- validate
Logical, whether to perform a train/test split. If TRUE, model performance is evaluated on a held-out test set. Validation is only performed when confounders are provided and an xgboost model is fitted.
- test_size
Numeric, proportion of data used for the test set. Only used when
validate = TRUE. Must be between 0 and 1.- seed
Integer, random seed for reproducibility of the train/test split.
Value
A list containing:
Mixture parameters (
mu,sigma,lambda).Fitted xgboost model object.
Training AUC (
train_auc).Cross-validated AUC from xgboost CV (
cv_auc).Test/validation AUC on held-out data (
test_auc, only ifvalidate = TRUE).Augmented dataset with columns:
p_disease(posterior probability from FMM) andadjusted_risk(confounder-adjusted risk score).
Details
This function implements a two-stage modeling pipeline:
Stage 1: Finite Mixture Model (FMM)
Fits a 2-component Gaussian mixture model to the biomarker distribution using the Expectation-Maximization (EM) algorithm (up to
maxititerations, toleranceepsilon).Estimates component means (\(\mu_1, \mu_2\)), standard deviations (\(\sigma_1, \sigma_2\)), and mixing proportions (\(\pi\)).
Computes the posterior probability of disease for each subject: $$\hat{p}(x) = \frac{\hat{\pi} \cdot N(x|\hat{\mu}_2,\hat{\sigma}_2)}{\hat{\pi} \cdot N(x|\hat{\mu}_2,\hat{\sigma}_2) + (1-\hat{\pi}) \cdot N(x|\hat{\mu}_1,\hat{\sigma}_1)}$$ where \(N(x|\mu,\sigma)\) is the Gaussian density.
The resulting
p_diseaserepresents the latent probability of disease given the biomarker value.
Stage 2: Confounder-Adjusted Risk Model (xgboost)
Trains a binary logistic xgboost model using predictors:
p_disease(from FMM) plus specified confounders.Model complexity (number of boosting iterations) is selected via cross-validation with early stopping.
Produces an
adjusted_riskscore in [0,1] for each subject, representing the confounder-adjusted probability of disease.
The disease component is identified using which.max(mu), assuming that
higher biomarker values correspond to disease. If this assumption does not
hold for your dataset, results may be misleading. A warning is issued if the assumption may not hold.
Examples
n <- 500
set.seed(123)
# outcome
DISEASE <- rbinom(n, 1, 0.35)
# biomarker depends on disease
PTAU <- rnorm(n, mean = 25 + 10 * DISEASE, sd = 8)
# confounders (optional noise)
AGE <- round(rnorm(n, 73, 7))
SEX <- sample(c(0, 1), n, replace = TRUE)
BMI <- rnorm(n, 25, 4)
HTN <- rbinom(n, 1, 0.3)
DM <- rbinom(n, 1, 0.2)
df <- data.frame(PTAU, AGE, SEX, BMI, HTN, DM, DISEASE)
res <- adjust_score(
df,
biomarker = "PTAU", outcome = "DISEASE",
confounders = c("AGE","SEX","BMI","HTN","DM"), validate = TRUE)
#> number of iterations= 704
#> Setting levels: control = 0, case = 1
#> Setting direction: controls < cases
#> Setting levels: control = 0, case = 1
#> Setting direction: controls < cases
head(res$data[,c("PTAU","p_disease","adjusted_risk")])
#> PTAU p_disease adjusted_risk
#> 1 21.99518 3.013220e-22 0.1192439
#> 2 30.50499 7.443839e-10 0.2046204
#> 3 22.24866 1.057691e-21 0.1260243
#> 4 35.72397 3.366296e-04 0.5474330
#> 5 47.78807 9.895697e-01 0.6416051
#> 6 24.29148 4.884413e-20 0.1675190
