From 1d68e2f3127fe4345292e64bc9c522f6ef0783a9 Mon Sep 17 00:00:00 2001 From: Craig Gower-Page Date: Tue, 18 Jun 2024 11:29:18 +0100 Subject: [PATCH] Convert linkGrowth to be log scale for SF and GSF (#357) --- R/SimLongitudinalGSF.R | 2 +- R/SimLongitudinalSteinFojo.R | 2 +- inst/stan/lm-gsf/link_growth.stan | 2 +- inst/stan/lm-stein-fojo/link_growth.stan | 2 +- tests/testthat/test-LongitudinalSteinFojo.R | 74 ++++++++++++++------- vignettes/statistical-specification.Rmd | 4 +- 6 files changed, 56 insertions(+), 30 deletions(-) diff --git a/R/SimLongitudinalGSF.R b/R/SimLongitudinalGSF.R index 1e717c7a7..c5ad6e122 100644 --- a/R/SimLongitudinalGSF.R +++ b/R/SimLongitudinalGSF.R @@ -140,7 +140,7 @@ sampleObservations.SimLongitudinalGSF <- function(object, times_df) { (object@link_dsld * .data$dsld) + (object@link_ttg * .data$ttg) + (object@link_identity * .data$mu_sld) + - (object@link_growth * .data$psi_g) + (object@link_growth * log(.data$psi_g)) ) } diff --git a/R/SimLongitudinalSteinFojo.R b/R/SimLongitudinalSteinFojo.R index 64f580951..69b7fdac1 100644 --- a/R/SimLongitudinalSteinFojo.R +++ b/R/SimLongitudinalSteinFojo.R @@ -126,7 +126,7 @@ sampleObservations.SimLongitudinalSteinFojo <- function(object, times_df) { (object@link_dsld * .data$dsld) + (object@link_ttg * .data$ttg) + (object@link_identity * .data$mu_sld) + - (object@link_growth * .data$psi_g) + (object@link_growth * log(.data$psi_g)) ) } diff --git a/inst/stan/lm-gsf/link_growth.stan b/inst/stan/lm-gsf/link_growth.stan index b035f2575..d16464b95 100644 --- a/inst/stan/lm-gsf/link_growth.stan +++ b/inst/stan/lm-gsf/link_growth.stan @@ -10,6 +10,6 @@ functions { ) { int nrows = rows(link_function_inputs); int ncols = cols(time); - return rep_matrix(link_function_inputs[,3], ncols); + return rep_matrix(log(link_function_inputs[,3]), ncols); } } diff --git a/inst/stan/lm-stein-fojo/link_growth.stan b/inst/stan/lm-stein-fojo/link_growth.stan index d791600b3..4baa34d17 100644 --- a/inst/stan/lm-stein-fojo/link_growth.stan +++ b/inst/stan/lm-stein-fojo/link_growth.stan @@ -10,6 +10,6 @@ functions { ) { int nrows = rows(link_function_inputs); int ncols = cols(time); - return rep_matrix(link_function_inputs[,3], ncols); + return rep_matrix(log(link_function_inputs[,3]), ncols); } } diff --git a/tests/testthat/test-LongitudinalSteinFojo.R b/tests/testthat/test-LongitudinalSteinFojo.R index 279394186..9af172365 100644 --- a/tests/testthat/test-LongitudinalSteinFojo.R +++ b/tests/testthat/test-LongitudinalSteinFojo.R @@ -229,44 +229,68 @@ test_that("Can recover known distributional parameters from a SF joint model wit skip_if_not(is_full_test()) - set.seed(7738) + sim_params <- list( + sigma = 0.005, + mu_s = log(c(0.15, 0.3)), + mu_g = log(c(0.4, 0.25)), + mu_b = log(60), + omega_b = 0.1, + omega_s = 0.1, + omega_g = 0.2, + link_ttg = 0, + link_dsld = 0, + link_growth = 1, + lambda = 2, + lambda_cen = 1 / 9000, + beta_cat_b = -0.1, + beta_cat_c = 0.5, + beta_cont = 0.3 + ) + + set.seed(2338) ## Generate Test data with known parameters jlist <- SimJointData( design = list( - SimGroup(170, "Arm-A", "Study-X"), - SimGroup(170, "Arm-B", "Study-X") + SimGroup(200, "Arm-A", "Study-X"), + SimGroup(200, "Arm-B", "Study-X") ), longitudinal = SimLongitudinalSteinFojo( times = c( - 1, 100, 150, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, + -100, -50, -10, 1, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 1100, 1300, 1500, 1800 ) / 365, - sigma = 0.005, - mu_s = log(c(0.15, 0.3)), - mu_g = log(c(0.4, 0.25)), - mu_b = log(60), - omega_b = 0.1, - omega_s = 0.1, - omega_g = 0.2, - link_ttg = 0, - link_dsld = 0, - link_growth = 3 + sigma = sim_params$sigma, + mu_s = sim_params$mu_s, + mu_g = sim_params$mu_g, + mu_b = sim_params$mu_b, + omega_b = sim_params$omega_b, + omega_s = sim_params$omega_s, + omega_g = sim_params$omega_g, + link_ttg = sim_params$link_ttg, + link_dsld = sim_params$link_dsld, + link_growth = sim_params$link_growth ), survival = SimSurvivalExponential( time_max = 4, time_step = 1 / 365, - lambda = 1, + lambda = sim_params$lambda, lambda_cen = 1 / 9000, beta_cat = c( "A" = 0, - "B" = -0.1, - "C" = 0.5 + "B" = sim_params$beta_cat_b, + "C" = sim_params$beta_cat_c ), - beta_cont = 0.3 + beta_cont = sim_params$beta_cont ), .silent = TRUE ) + # nolint startā  + ### Diagnostics helpers + # plot(survival::survfit(Surv(time, event) ~ 1, data = jlist@survival)) + # median(jlist@survival$time) + # nolint end + jm <- JointModel( longitudinal = LongitudinalSteinFojo( @@ -284,10 +308,10 @@ test_that("Can recover known distributional parameters from a SF joint model wit ), survival = SurvivalExponential( - lambda = prior_lognormal(log(1), 0.5) + lambda = prior_lognormal(log(2), 0.5) ), link = Link( - linkGrowth(prior_normal(0, 4)) + linkGrowth(prior_normal(0, 2)) ) ) @@ -347,17 +371,19 @@ test_that("Can recover known distributional parameters from a SF joint model wit c("lm_sf_mu_bsld", "lm_sf_mu_ks", "lm_sf_mu_kg"), TRUE ) - true_values <- c(60, 0.15, 0.3, 0.4, 0.25) + true_values <- exp(c(sim_params$mu_b, sim_params$mu_s, sim_params$mu_g)) expect_true(all(dat$q01 <= true_values)) expect_true(all(dat$q99 >= true_values)) expect_true(all(dat$ess_bulk > 100)) dat <- summary_post( as.CmdStanMCMC(mp), - c("link_growth", "sm_exp_lambda") + c("link_growth", "sm_exp_lambda", "beta_os_cov") + ) + true_values <- c( + sim_params$link_growth, sim_params$lambda, + sim_params$beta_cat_b, sim_params$beta_cat_c, sim_params$beta_cont ) - - true_values <- c(3, 1) expect_true(all(dat$q01 <= true_values)) expect_true(all(dat$q99 >= true_values)) expect_true(all(dat$ess_bulk > 100)) diff --git a/vignettes/statistical-specification.Rmd b/vignettes/statistical-specification.Rmd index b3b83e902..ac75248c1 100644 --- a/vignettes/statistical-specification.Rmd +++ b/vignettes/statistical-specification.Rmd @@ -229,7 +229,7 @@ Accessible via `linkIdentity()` $$ \begin{align*} -G(t \mid b_i, s_i, g_i) &= g_i +G(t \mid b_i, s_i, g_i) &= log(g_i) \end{align*} $$ @@ -341,7 +341,7 @@ Accessible via `linkIdentity()` $$ \begin{align*} -G(t \mid b_i, s_i, g_i, \phi_i) &= g_i +G(t \mid b_i, s_i, g_i, \phi_i) &= log(g_i) \end{align*} $$