1library(glmnet)
2predictors <- c('age', 'baseline_score')
3stopifnot(all(c('patient_id', predictors, 'outcome') %in% names(train)),
4 all(c('patient_id', predictors) %in% names(test)))
5stopifnot(!anyNA(train$patient_id), !anyNA(test$patient_id))
6stopifnot(!anyDuplicated(train$patient_id), !anyDuplicated(test$patient_id))
7stopifnot(length(intersect(train$patient_id, test$patient_id)) == 0L)
8stopifnot(all(vapply(train[predictors], is.numeric, logical(1))),
9 all(vapply(test[predictors], is.numeric, logical(1))))
10x <- as.matrix(train[, predictors, drop = FALSE])
11x_test <- as.matrix(test[, predictors, drop = FALSE])
12y <- train$outcome
13stopifnot(all(is.finite(x)), all(is.finite(x_test)),
14 !anyNA(y), all(y %in% c(0, 1)), length(unique(y)) == 2L)
15stopifnot(min(table(y)) >= 5L, identical(colnames(x), colnames(x_test)))
16set.seed(2026)
17foldid <- integer(length(y))
18for (value in c(0, 1)) {
19 rows <- which(y == value)
20 foldid[rows] <- sample(rep(seq_len(5L), length.out = length(rows)))
21}
22fit <- cv.glmnet(x, y, family = 'binomial', alpha = 1,
23 foldid = foldid, type.measure = 'deviance')
24prob <- drop(predict(fit, newx = x_test, s = 'lambda.1se', type = 'response'))