Skip to content

Commit 33a06fa

Browse files
committed
working COP model
1 parent 3165fbe commit 33a06fa

File tree

6 files changed

+21
-316
lines changed

6 files changed

+21
-316
lines changed

R/SeroCOP.R

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,6 @@ SeroCOP <- R6::R6Class(
150150
#' @param thin Thinning interval (default: 1)
151151
#' @param ... Additional arguments passed to rstan::sampling
152152
#' @return Self (invisibly)
153-
#' @description
154-
#' Fits a Bayesian logistic model using Stan.
155-
#' @param chains Number of MCMC chains (default: 4).
156-
#' @param iter Total number of iterations per chain (default: 2000).
157-
#' @param warmup Number of warmup iterations per chain (default: 1000).
158-
#' @param thin Thinning interval for samples (default: 1).
159-
#' @param ... Additional arguments passed to `rstan::stan`.
160-
#' @return The fitted model object (invisible).
161-
#' @examples
162-
#' sero <- SeroCOP$new()
163-
#' sero$fit_model(chains = 4, iter = 2000)
164153
fit_model = function(chains = 4, iter = 2000, warmup = 1000, thin = 1, ...) {
165154
message("Fitting Bayesian logistic model...")
166155

@@ -217,14 +206,6 @@ SeroCOP <- R6::R6Class(
217206
#' Get posterior predictions for infection probability
218207
#' @param newdata Optional new titre values for prediction
219208
#' @return Matrix of posterior predictions (iterations x observations)
220-
#' @description
221-
#' Generates posterior predictions for infection probability.
222-
#' @param newdata Optional new titre values for prediction.
223-
#' @return A matrix of posterior predictions (iterations x observations).
224-
#' @examples
225-
#' sero <- SeroCOP$new()
226-
#' sero$fit_model()
227-
#' predictions <- sero$predict()
228209
predict = function(newdata = NULL) {
229210
if (is.null(self$fit)) {
230211
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -256,10 +237,6 @@ SeroCOP <- R6::R6Class(
256237
#' Extract probability of protection from the fitted model
257238
#' @param newdata Optional vector of new titre values for prediction
258239
#' @return Matrix of protection probabilities (rows = MCMC samples, cols = observations)
259-
#' @examples
260-
#' sero <- SeroCOP$new()
261-
#' sero$fit_model()
262-
#' protection <- sero$predict_protection()
263240
predict_protection = function(newdata = NULL) {
264241
if (is.null(self$fit)) {
265242
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -294,13 +271,6 @@ SeroCOP <- R6::R6Class(
294271
#' @description
295272
#' Get summary statistics for model parameters
296273
#' @return Data frame with parameter summaries
297-
#' @description
298-
#' Provides summary statistics for model parameters.
299-
#' @return A data frame with parameter summaries.
300-
#' @examples
301-
#' sero <- SeroCOP$new()
302-
#' sero$fit_model()
303-
#' summary <- sero$summary()
304274
summary = function() {
305275
if (is.null(self$fit)) {
306276
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -316,13 +286,6 @@ SeroCOP <- R6::R6Class(
316286
#' @description
317287
#' Calculate performance metrics
318288
#' @return List containing ROC AUC, Brier score, and LOO-CV metrics
319-
#' @description
320-
#' Calculates performance metrics such as ROC AUC, Brier score, and LOO-CV metrics.
321-
#' @return A list containing performance metrics.
322-
#' @examples
323-
#' sero <- SeroCOP$new()
324-
#' sero$fit_model()
325-
#' metrics <- sero$get_metrics()
326289
get_metrics = function() {
327290
if (is.null(self$fit)) {
328291
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -365,15 +328,6 @@ SeroCOP <- R6::R6Class(
365328
#' @param title Plot title
366329
#' @param ... Additional arguments passed to ggplot2
367330
#' @return A ggplot object
368-
#' @description
369-
#' Plots the fitted curve with uncertainty.
370-
#' @param title Title of the plot (default: "Correlates of Risk Curve").
371-
#' @param ... Additional arguments passed to `ggplot2`.
372-
#' @return A ggplot object.
373-
#' @examples
374-
#' sero <- SeroCOP$new()
375-
#' sero$fit_model()
376-
#' plot <- sero$plot_curve()
377331
plot_curve = function(title = "Correlates of Risk Curve", ...) {
378332
if (is.null(self$fit)) {
379333
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -436,14 +390,6 @@ SeroCOP <- R6::R6Class(
436390
#' Plot ROC curve
437391
#' @param title Plot title
438392
#' @return A ggplot object
439-
#' @description
440-
#' Plots the ROC curve.
441-
#' @param title Title of the plot (default: "ROC Curve").
442-
#' @return A ggplot object.
443-
#' @examples
444-
#' sero <- SeroCOP$new()
445-
#' sero$fit_model()
446-
#' roc_plot <- sero$plot_roc()
447393
plot_roc = function(title = "ROC Curve") {
448394
if (is.null(self$fit)) {
449395
stop("Model has not been fitted yet. Run fit_model() first.")
@@ -479,14 +425,7 @@ SeroCOP <- R6::R6Class(
479425
#' @description
480426
#' Plot posterior distributions of parameters
481427
#' @return A ggplot object
482-
#' @description
483-
#' Visualizes posterior distributions of parameters.
484-
#' @return A ggplot object.
485-
#' @examples
486-
#' sero <- SeroCOP$new()
487-
#' sero$fit_model()
488-
#' param_plot <- sero$plot_parameters()
489-
plot_parameters = function() {
428+
plot_posteriors = function() {
490429
if (is.null(self$fit)) {
491430
stop("Model has not been fitted yet. Run fit_model() first.")
492431
}
@@ -528,10 +467,6 @@ SeroCOP <- R6::R6Class(
528467
#' @param correlate_of_risk Numeric vector of correlates of risk.
529468
#' @param upper_bound Numeric value for the upper bound (default: 0.7).
530469
#' @return Numeric vector of correlates of protection.
531-
#' @examples
532-
#' sero <- SeroCOP$new(titre = titre, infected = infected)
533-
#' sero$fit_model()
534-
#' cor <- sero$extract_cop(correlate_of_risk = c(0.1, 0.2), upper_bound = 0.7)
535470
extract_cop = function(correlate_of_risk, upper_bound = 0.7) {
536471
if (missing(correlate_of_risk)) {
537472
stop("correlate_of_risk must be provided")
@@ -548,15 +483,9 @@ SeroCOP <- R6::R6Class(
548483
),
549484

550485
private = list(
551-
#' @description
552-
#' Get default prior distributions based on data
553-
#' @return List of default prior parameters
554-
#' @description
555-
#' Generates default prior distributions based on the data.
556-
#' @return A list of default prior parameters.
557-
#' @examples
558-
#' sero <- SeroCOP$new()
559-
#' priors <- sero$get_default_priors()
486+
# Get default prior distributions based on data
487+
# Internal method - generates default prior distributions based on the data
488+
# Returns a list of default prior parameters
560489
get_default_priors = function() {
561490
# Calculate data-driven defaults for ec50
562491
titre_midpoint <- (max(self$titre) + min(self$titre)) / 2

R/SeroCOPMulti.R

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,6 @@ SeroCOPMulti <- R6::R6Class(
307307
#' @param correlate_of_risk_list List of numeric vectors of correlates of risk for each biomarker.
308308
#' @param upper_bound Numeric value for the upper bound (default: 0.7).
309309
#' @return List of numeric vectors of correlates of protection for each biomarker.
310-
#' @examples
311-
#' multi_model <- SeroCOPMulti$new(titre = titre_matrix, infected = infected)
312-
#' multi_model$fit_all()
313-
#' cor_list <- list(IgG = c(0.1, 0.2), IgA = c(0.3, 0.4))
314-
#' cop_list <- multi_model$extract_cop_multi(correlate_of_risk_list = cor_list, upper_bound = 0.7)
315310
extract_cop_multi = function(correlate_of_risk_list, upper_bound = 0.7) {
316311
if (!is.list(correlate_of_risk_list)) {
317312
stop("correlate_of_risk_list must be a list of numeric vectors")

R/utils.R

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ simulate_serocop_data <- function(n = 200,
5555
if (n <= 0) stop("n must be positive")
5656

5757
# Generate titres
58-
titre <- rnorm(n, mean = titre_mean, sd = titre_sd)
58+
titre <- stats::rnorm(n, mean = titre_mean, sd = titre_sd)
5959

6060
# Calculate infection probabilities
6161
prob_true <- floor + (ceiling - floor) / (1 + exp(slope * (titre - ec50)))
6262

6363
# Generate infection outcomes
64-
infected <- rbinom(n, size = 1, prob = prob_true)
64+
infected <- stats::rbinom(n, size = 1, prob = prob_true)
6565

6666
# Return results
6767
list(
@@ -137,16 +137,16 @@ extract_parameters <- function(serocop_obj, prob = 0.95) {
137137
parameter = c("floor", "ceiling", "ec50", "slope"),
138138
mean = c(mean(params$floor), mean(params$ceiling),
139139
mean(params$ec50), mean(params$slope)),
140-
median = c(median(params$floor), median(params$ceiling),
141-
median(params$ec50), median(params$slope)),
142-
lower = c(quantile(params$floor, probs[1]),
143-
quantile(params$ceiling, probs[1]),
144-
quantile(params$ec50, probs[1]),
145-
quantile(params$slope, probs[1])),
146-
upper = c(quantile(params$floor, probs[3]),
147-
quantile(params$ceiling, probs[3]),
148-
quantile(params$ec50, probs[3]),
149-
quantile(params$slope, probs[3]))
140+
median = c(stats::median(params$floor), stats::median(params$ceiling),
141+
stats::median(params$ec50), stats::median(params$slope)),
142+
lower = c(stats::quantile(params$floor, probs[1]),
143+
stats::quantile(params$ceiling, probs[1]),
144+
stats::quantile(params$ec50, probs[1]),
145+
stats::quantile(params$slope, probs[1])),
146+
upper = c(stats::quantile(params$floor, probs[3]),
147+
stats::quantile(params$ceiling, probs[3]),
148+
stats::quantile(params$ec50, probs[3]),
149+
stats::quantile(params$slope, probs[3]))
150150
)
151151

152152
rownames(result) <- NULL

0 commit comments

Comments
 (0)