From 3b15daaf373ebc36da2eb92f2e37ed569731f07d Mon Sep 17 00:00:00 2001 From: Johannes Ranke Date: Wed, 9 Dec 2020 13:08:01 +0100 Subject: More tests --- R/nlme.mmkin.R | 2 +- R/summary.nlme.mmkin.R | 8 +- .../plotting/mixed-model-fit-for-nlme-object.svg | 3745 +++++++------------- tests/testthat/print_mmkin_biphasic_mixed.txt | 4 +- tests/testthat/print_nlme_biphasic.txt | 29 + tests/testthat/setup_script.R | 12 +- tests/testthat/summary_nlme_biphasic_s.txt | 81 + tests/testthat/test_mixed.R | 128 +- tests/testthat/test_plot.R | 4 +- tests/testthat/test_saem.R | 133 - 10 files changed, 1533 insertions(+), 2613 deletions(-) create mode 100644 tests/testthat/print_nlme_biphasic.txt create mode 100644 tests/testthat/summary_nlme_biphasic_s.txt delete mode 100644 tests/testthat/test_saem.R diff --git a/R/nlme.mmkin.R b/R/nlme.mmkin.R index c6f15c8e..82d5f6de 100644 --- a/R/nlme.mmkin.R +++ b/R/nlme.mmkin.R @@ -230,7 +230,7 @@ print.nlme.mmkin <- function(x, digits = max(3, getOption("digits") - 3), ...) { length(unique(x$data$name)), "variable(s) grouped in", length(unique(x$data$ds)), "datasets\n") cat("\nLog-", if(x$method == "REML") "restricted-" else "", - "likelihood: ", format(x$logLik), "\n", sep = "") + "likelihood: ", format(x$logLik, digits = digits), "\n", sep = "") fixF <- x$call$fixed cat("\nFixed effects:\n", deparse( diff --git a/R/summary.nlme.mmkin.R b/R/summary.nlme.mmkin.R index 29f1207b..b42d5d7b 100644 --- a/R/summary.nlme.mmkin.R +++ b/R/summary.nlme.mmkin.R @@ -184,15 +184,15 @@ print.summary.nlme.mmkin <- function(x, digits = max(3, getOption("digits") - 3) tc = "Two-component variance function"), "\n") cat("\nMean of starting values for individual parameters:\n") - print(x$mean_dp_start) + print(x$mean_dp_start, digits = digits) cat("\nFixed degradation parameter values:\n") if(length(x$fixed$value) == 0) cat("None\n") - else print(x$fixed) + else print(x$fixed, digits = digits) cat("\nResults:\n\n") print(data.frame(AIC = x$AIC, BIC = x$BIC, logLik = x$logLik, - row.names = " "), ...) + row.names = " "), digits = digits, ...) cat("\nOptimised, transformed parameters with symmetric confidence intervals:\n") print(x$confint_trans, digits = digits, ...) @@ -220,7 +220,7 @@ print.summary.nlme.mmkin <- function(x, digits = max(3, getOption("digits") - 3) printff <- !is.null(x$ff) if(printff){ cat("\nResulting formation fractions:\n") - print(data.frame(ff = x$ff), ...) + print(data.frame(ff = x$ff), digits = digits, ...) } printdistimes <- !is.null(x$distimes) diff --git a/tests/figs/plotting/mixed-model-fit-for-nlme-object.svg b/tests/figs/plotting/mixed-model-fit-for-nlme-object.svg index 9d7fe5cf..23bf722c 100644 --- a/tests/figs/plotting/mixed-model-fit-for-nlme-object.svg +++ b/tests/figs/plotting/mixed-model-fit-for-nlme-object.svg @@ -13,720 +13,720 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Population -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Population +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 - - + + - + - - - - - - - - -0 -20 -40 -60 -80 -100 -120 - - - - - - - -0 -20 -40 -60 -80 -100 - + + + + + + + + +0 +20 +40 +60 +80 +100 +120 + + + + + + + +0 +20 +40 +60 +80 +100 + - - + + -Time -parent +Time +parent - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -734,1749 +734,622 @@ - - - - - - - -0 -20 -40 -60 -80 -100 - - - - - - --4 --2 -0 -2 -4 - + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + +-3 +-2 +-1 +0 +1 +2 +3 + - - + + -Predicted -Standardized residual +Predicted +Standardized residual - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 -20 -40 -60 -80 -100 -120 - - - - - - -0 -10 -20 -30 -40 - - - - - - -Time -m1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 -10 -20 -30 -40 - - - - - - --4 --2 -0 -2 -4 - - - - - - -Predicted -Standardized residual - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/print_mmkin_biphasic_mixed.txt b/tests/testthat/print_mmkin_biphasic_mixed.txt index 3d92b120..62e485ac 100644 --- a/tests/testthat/print_mmkin_biphasic_mixed.txt +++ b/tests/testthat/print_mmkin_biphasic_mixed.txt @@ -21,6 +21,6 @@ OK: No warnings Mean fitted parameters: parent_0 log_k_m1 f_parent_qlogis log_k1 log_k2 - 100.700 -6.299 -0.078 -3.094 -3.954 + 100.70048940 -6.29941397 -0.07845907 -3.09354444 -3.95368996 g_qlogis - 0.027 + 0.02729554 diff --git a/tests/testthat/print_nlme_biphasic.txt b/tests/testthat/print_nlme_biphasic.txt new file mode 100644 index 00000000..9ea84d44 --- /dev/null +++ b/tests/testthat/print_nlme_biphasic.txt @@ -0,0 +1,29 @@ +Kinetic nonlinear mixed-effects model fit by maximum likelihood + +Structural model: +d_parent/dt = - ((k1 * g * exp(-k1 * time) + k2 * (1 - g) * exp(-k2 * + time)) / (g * exp(-k1 * time) + (1 - g) * exp(-k2 * time))) + * parent +d_m1/dt = + f_parent_to_m1 * ((k1 * g * exp(-k1 * time) + k2 * (1 - g) + * exp(-k2 * time)) / (g * exp(-k1 * time) + (1 - g) * + exp(-k2 * time))) * parent - k_m1 * m1 + +Data: +509 observations of 2 variable(s) grouped in 15 datasets + +Log-likelihood: -1343 + +Fixed effects: + list(parent_0 ~ 1, log_k_m1 ~ 1, f_parent_qlogis ~ 1, log_k1 ~ 1, log_k2 ~ 1, g_qlogis ~ 1) + parent_0 log_k_m1 f_parent_qlogis log_k1 log_k2 + 100.365 -6.231 -0.078 -3.224 -4.098 + g_qlogis + -0.105 + +Random effects: + Formula: list(parent_0 ~ 1, log_k_m1 ~ 1, f_parent_qlogis ~ 1, log_k1 ~ 1, log_k2 ~ 1, g_qlogis ~ 1) + Level: ds + Structure: Diagonal + parent_0 log_k_m1 f_parent_qlogis log_k1 log_k2 g_qlogis Residual +StdDev: 1.1 0.00017 0.28 0.74 0.82 0.28 2.7 + diff --git a/tests/testthat/setup_script.R b/tests/testthat/setup_script.R index 1bedbf65..e3b56fb3 100644 --- a/tests/testthat/setup_script.R +++ b/tests/testthat/setup_script.R @@ -94,7 +94,7 @@ fit_obs_1 <- mkinfit(m_synth_SFO_lin, SFO_lin_a, error_model = "obs", quiet = TR fit_tc_1 <- mkinfit(m_synth_SFO_lin, SFO_lin_a, error_model = "tc", quiet = TRUE, error_model_algorithm = "threestep") -# Mixed models data +# Mixed models data and set.seed(123456) sampling_times = c(0, 1, 3, 7, 14, 28, 60, 90, 120) n <- n_biphasic <- 15 @@ -153,6 +153,12 @@ ds_biphasic <- lapply(ds_biphasic_mean, function(ds) { # Mixed model fits mmkin_sfo_1 <- mmkin("SFO", ds_sfo, quiet = TRUE, error_model = "tc") sfo_saemix_1 <- saem(mmkin_sfo_1, quiet = TRUE, transformations = "saemix") + +mmkin_dfop_1 <- mmkin("DFOP", ds_dfop, quiet = TRUE) +dfop_saemix_1 <- saem(mmkin_dfop_1, quiet = TRUE, transformations = "mkin") +dfop_saemix_2 <- saem(mmkin_dfop_1, quiet = TRUE, transformations = "saemix") +dfop_nlme_1 <- nlme(mmkin_dfop_1) + mmkin_biphasic <- mmkin(list("DFOP-SFO" = DFOP_SFO), ds_biphasic, quiet = TRUE) mmkin_biphasic_mixed <- mixed(mmkin_biphasic) nlme_biphasic <- nlme(mmkin_biphasic) @@ -163,9 +169,9 @@ ds_uba <- lapply(experimental_data_for_UBA_2019[6:10], function(x) subset(x$data[c("name", "time", "value")])) names(ds_uba) <- paste("Dataset", 6:10) sfo_sfo_uba <- mkinmod(parent = mkinsub("SFO", "A1"), - A1 = mkinsub("SFO")) + A1 = mkinsub("SFO"), quiet = TRUE) dfop_sfo_uba <- mkinmod(parent = mkinsub("DFOP", "A1"), - A1 = mkinsub("SFO")) + A1 = mkinsub("SFO"), quiet = TRUE) f_uba_mmkin <- mmkin(list("SFO-SFO" = sfo_sfo_uba, "DFOP-SFO" = dfop_sfo_uba), ds_uba, quiet = TRUE) f_uba_dfop_sfo_mixed <- mixed(f_uba_mmkin[2, ]) diff --git a/tests/testthat/summary_nlme_biphasic_s.txt b/tests/testthat/summary_nlme_biphasic_s.txt new file mode 100644 index 00000000..1e4c3c14 --- /dev/null +++ b/tests/testthat/summary_nlme_biphasic_s.txt @@ -0,0 +1,81 @@ +nlme version used for fitting: Dummy 0.0 for testing +mkin version used for pre-fitting: Dummy 0.0 for testing +R version used for fitting: Dummy R version for testing +Date of fit: Dummy date for testing +Date of summary: Dummy date for testing + +Equations: +d_parent/dt = - ((k1 * g * exp(-k1 * time) + k2 * (1 - g) * exp(-k2 * + time)) / (g * exp(-k1 * time) + (1 - g) * exp(-k2 * time))) + * parent +d_m1/dt = + f_parent_to_m1 * ((k1 * g * exp(-k1 * time) + k2 * (1 - g) + * exp(-k2 * time)) / (g * exp(-k1 * time) + (1 - g) * + exp(-k2 * time))) * parent - k_m1 * m1 + +Data: +509 observations of 2 variable(s) grouped in 15 datasets + +Model predictions using solution type analytical + +Fitted in test time 0 s using 2 iterations + +Variance model: Constant variance + +Mean of starting values for individual parameters: + parent_0 log_k_m1 f_parent_qlogis log_k1 log_k2 + 100.700 -6.299 -0.078 -3.094 -3.954 + g_qlogis + 0.027 + +Fixed degradation parameter values: + value type +m1_0 0 state + +Results: + + AIC BIC logLik + 2711 2766 -1343 + +Optimised, transformed parameters with symmetric confidence intervals: + lower est. upper +parent_0 99.50 100.365 101.229 +log_k_m1 -6.53 -6.231 -5.936 +f_parent_qlogis -0.24 -0.078 0.084 +log_k1 -3.61 -3.224 -2.839 +log_k2 -4.52 -4.098 -3.677 +g_qlogis -0.38 -0.105 0.172 + +Correlation: + prnt_0 lg_k_1 f_prn_ log_k1 log_k2 +log_k_m1 -0.185 +f_parent_qlogis -0.161 0.405 +log_k1 0.056 -0.014 -0.016 +log_k2 0.025 0.011 -0.004 0.026 +g_qlogis -0.032 -0.046 -0.012 -0.109 -0.103 + +Random effects: + Formula: list(parent_0 ~ 1, log_k_m1 ~ 1, f_parent_qlogis ~ 1, log_k1 ~ 1, log_k2 ~ 1, g_qlogis ~ 1) + Level: ds + Structure: Diagonal + parent_0 log_k_m1 f_parent_qlogis log_k1 log_k2 g_qlogis Residual +StdDev: 1.1 0.00017 0.28 0.74 0.82 0.28 2.7 + + +Backtransformed parameters with asymmetric confidence intervals: + lower est. upper +parent_0 1.0e+02 100.365 1.0e+02 +k_m1 1.5e-03 0.002 2.6e-03 +f_parent_to_m1 4.4e-01 0.480 5.2e-01 +k1 2.7e-02 0.040 5.9e-02 +k2 1.1e-02 0.017 2.5e-02 +g 4.1e-01 0.474 5.4e-01 + +Resulting formation fractions: + ff +parent_m1 0.48 +parent_sink 0.52 + +Estimated disappearance times: + DT50 DT90 DT50back DT50_k1 DT50_k2 +parent 27 105 31 17 42 +m1 352 1171 NA NA NA diff --git a/tests/testthat/test_mixed.R b/tests/testthat/test_mixed.R index 2d69e13e..b9713c6e 100644 --- a/tests/testthat/test_mixed.R +++ b/tests/testthat/test_mixed.R @@ -1,35 +1,97 @@ -context("Fitting of nonlinear mixed effects models") - -sampling_times = c(0, 1, 3, 7, 14, 28, 60, 90, 120) -n_biphasic <- 8 -err_1 = list(const = 1, prop = 0.07) - -DFOP_SFO <- mkinmod( - parent = mkinsub("DFOP", "m1"), - m1 = mkinsub("SFO"), - quiet = TRUE) - -set.seed(123456) -log_sd <- 0.3 -syn_biphasic_parms <- as.matrix(data.frame( - k1 = rlnorm(n_biphasic, log(0.05), log_sd), - k2 = rlnorm(n_biphasic, log(0.01), log_sd), - g = plogis(rnorm(n_biphasic, 0, log_sd)), - f_parent_to_m1 = plogis(rnorm(n_biphasic, 0, log_sd)), - k_m1 = rlnorm(n_biphasic, log(0.002), log_sd))) - -ds_biphasic_mean <- lapply(1:n_biphasic, - function(i) { - mkinpredict(DFOP_SFO, syn_biphasic_parms[i, ], - c(parent = 100, m1 = 0), sampling_times) - } -) - -set.seed(123456L) -ds_biphasic <- lapply(ds_biphasic_mean, function(ds) { - add_err(ds, - sdfunc = function(value) sqrt(err_1$const^2 + value^2 * err_1$prop^2), - n = 1, secondary = "m1")[[1]] +context("Nonlinear mixed effects models") + +test_that("Parent only models can be fitted using nonlinear mixed effects models", { + # Some fits were done in the setup script + mmkin_sfo_2 <- mmkin("SFO", ds_sfo, fixed_initials = c(parent = 100), quiet = TRUE) + + sfo_saemix_2 <- saem(mmkin_sfo_1, quiet = TRUE, transformations = "mkin") + sfo_saemix_3 <- expect_error(saem(mmkin_sfo_2, quiet = TRUE), "at least two parameters") + s_sfo_s1 <- summary(sfo_saemix_1) + s_sfo_s2 <- summary(sfo_saemix_2) + + sfo_nlme_1 <- expect_warning(nlme(mmkin_sfo_1), "not converge") + s_sfo_n <- summary(sfo_nlme_1) + + # Compare with input + expect_equal(round(s_sfo_s2$confint_ranef["SD.log_k_parent", "est."], 1), 0.3) + # k_parent is a bit different from input 0.03 here + expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), 0.035) + expect_equal(round(s_sfo_s2$confint_back["k_parent", "est."], 3), 0.035) + + # But the result is pretty unanimous between methods + expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), + round(s_sfo_s2$confint_back["k_parent", "est."], 3)) + expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), + round(s_sfo_n$confint_back["k_parent", "est."], 3)) + + s_dfop_s1 <- summary(dfop_saemix_1) + s_dfop_s2 <- summary(dfop_saemix_2) + s_dfop_n <- summary(dfop_nlme_1) + + dfop_pop <- as.numeric(dfop_pop) + expect_true(all(s_dfop_s1$confint_back[, "lower"] < dfop_pop)) + expect_true(all(s_dfop_s1$confint_back[, "upper"] > dfop_pop)) + expect_true(all(s_dfop_s2$confint_back[, "lower"] < dfop_pop)) + expect_true(all(s_dfop_s2$confint_back[, "upper"] > dfop_pop)) + + + # We get < 20% deviations with transformations made in mkin + rel_diff_1 <- (s_dfop_s1$confint_back[, "est."] - dfop_pop) / dfop_pop + expect_true(all(rel_diff_1 < 0.2)) + + # We get < 8% deviations with transformations made in saemix + rel_diff_2 <- (s_dfop_s2$confint_back[, "est."] - dfop_pop) / dfop_pop + expect_true(all(rel_diff_2 < 0.08)) +}) + +test_that("Print methods work", { + expect_known_output(print(mmkin_biphasic_mixed, digits = 2), "print_mmkin_biphasic_mixed.txt") + expect_known_output(print(nlme_biphasic, digits = 2), "print_nlme_biphasic.txt") + expect_known_output(print(sfo_saemix_1, digits = 1), "print_sfo_saemix_1.txt") +}) + +test_that("nlme results are reproducible", { + + test_summary <- summary(nlme_biphasic) + test_summary$nlmeversion <- "Dummy 0.0 for testing" + test_summary$mkinversion <- "Dummy 0.0 for testing" + test_summary$Rversion <- "Dummy R version for testing" + test_summary$date.fit <- "Dummy date for testing" + test_summary$date.summary <- "Dummy date for testing" + test_summary$time <- c(elapsed = "test time 0") + + expect_known_output(print(test_summary, digits = 2), "summary_nlme_biphasic_s.txt") + + dfop_sfo_pop <- as.numeric(dfop_sfo_pop) + ci_dfop_sfo_n <- summary(nlme_biphasic)$confint_back + # expect_true(all(ci_dfop_sfo_n[, "lower"] < dfop_sfo_pop)) # k2 is overestimated + expect_true(all(ci_dfop_sfo_n[, "upper"] > dfop_sfo_pop)) +}) + +test_that("saem results are reproducible for biphasic fits", { + + test_summary <- summary(saem_biphasic_s) + test_summary$saemixversion <- "Dummy 0.0 for testing" + test_summary$mkinversion <- "Dummy 0.0 for testing" + test_summary$Rversion <- "Dummy R version for testing" + test_summary$date.fit <- "Dummy date for testing" + test_summary$date.summary <- "Dummy date for testing" + test_summary$time <- c(elapsed = "test time 0") + + expect_known_output(print(test_summary, digits = 2), "summary_saem_biphasic_s.txt") + + dfop_sfo_pop <- as.numeric(dfop_sfo_pop) + ci_dfop_sfo_s_s <- summary(saem_biphasic_s)$confint_back + expect_true(all(ci_dfop_sfo_s_s[, "lower"] < dfop_sfo_pop)) + expect_true(all(ci_dfop_sfo_s_s[, "upper"] > dfop_sfo_pop)) + + # The following does not work, as k1 and k2 are not fitted well + ci_dfop_sfo_s_m <- summary(saem_biphasic_m)$confint_back + # expect_true(all(ci_dfop_sfo_s_m[, "lower"] < dfop_sfo_pop)) + # expect_true(all(ci_dfop_sfo_s_m[, "upper"] > dfop_sfo_pop)) + + # Somehow this does not work at the moment. But it took forever (~ 10 min) anyways... + #saem_biphasic_2 <- saem(mmkin_biphasic, solution_type = "deSolve", quiet = TRUE) + }) -f_mmkin <- mmkin(list("DFOP-SFO" = DFOP_SFO), ds_biphasic, quiet = TRUE) diff --git a/tests/testthat/test_plot.R b/tests/testthat/test_plot.R index db44c850..ae2841c0 100644 --- a/tests/testthat/test_plot.R +++ b/tests/testthat/test_plot.R @@ -35,6 +35,9 @@ test_that("Plotting mkinfit and mmkin objects is reproducible", { plot_biphasic_mmkin <- function() plot(f_uba_dfop_sfo_mixed) vdiffr::expect_doppelganger("mixed model fit for mmkin object", plot_biphasic_mmkin) + plot_biphasic_nlme <- function() plot(dfop_nlme_1) + vdiffr::expect_doppelganger("mixed model fit for nlme object", plot_biphasic_nlme) + plot_biphasic_saem_s <- function() plot(f_uba_dfop_sfo_saem) vdiffr::expect_doppelganger("mixed model fit for saem object with saemix transformations", plot_biphasic_saem_s) @@ -46,7 +49,6 @@ test_that("Plotting mkinfit and mmkin objects is reproducible", { #plot_biphasic_saem_s <- function() plot(saem_biphasic_s) plot_biphasic_saem_m <- function() plot(saem_biphasic_m) - vdiffr::expect_doppelganger("mixed model fit for nlme object", plot_biphasic_nlme) vdiffr::expect_doppelganger("mixed model fit for saem object with mkin transformations", plot_biphasic_saem_m) # different results when working with eigenvalues diff --git a/tests/testthat/test_saem.R b/tests/testthat/test_saem.R deleted file mode 100644 index aa32d0b5..00000000 --- a/tests/testthat/test_saem.R +++ /dev/null @@ -1,133 +0,0 @@ -context("Nonlinear mixed effects models fitted with SAEM from saemix") - -set.seed(123456) -sampling_times = c(0, 1, 3, 7, 14, 28, 60, 90, 120) -n <- n_biphasic <- 15 -log_sd <- 0.3 -err_1 = list(const = 1, prop = 0.05) -tc <- function(value) sigma_twocomp(value, err_1$const, err_1$prop) -const <- function(value) 2 - -SFO <- mkinmod(parent = mkinsub("SFO")) -k_parent = rlnorm(n, log(0.03), log_sd) -ds_sfo <- lapply(1:n, function(i) { - ds_mean <- mkinpredict(SFO, c(k_parent = k_parent[i]), - c(parent = 100), sampling_times) - add_err(ds_mean, tc, n = 1)[[1]] -}) - -DFOP <- mkinmod(parent = mkinsub("DFOP")) -dfop_pop <- list(parent_0 = 100, k1 = 0.06, k2 = 0.015, g = 0.4) -dfop_parms <- as.matrix(data.frame( - k1 = rlnorm(n, log(dfop_pop$k1), log_sd), - k2 = rlnorm(n, log(dfop_pop$k2), log_sd), - g = plogis(rnorm(n, qlogis(dfop_pop$g), log_sd)))) -ds_dfop <- lapply(1:n, function(i) { - ds_mean <- mkinpredict(DFOP, dfop_parms[i, ], - c(parent = dfop_pop$parent_0), sampling_times) - add_err(ds_mean, const, n = 1)[[1]] -}) - -set.seed(123456) -DFOP_SFO <- mkinmod( - parent = mkinsub("DFOP", "m1"), - m1 = mkinsub("SFO"), - quiet = TRUE) -syn_biphasic_parms <- as.matrix(data.frame( - k1 = rlnorm(n_biphasic, log(0.05), log_sd), - k2 = rlnorm(n_biphasic, log(0.01), log_sd), - g = plogis(rnorm(n_biphasic, 0, log_sd)), - f_parent_to_m1 = plogis(rnorm(n_biphasic, 0, log_sd)), - k_m1 = rlnorm(n_biphasic, log(0.002), log_sd))) -ds_biphasic_mean <- lapply(1:n_biphasic, - function(i) { - mkinpredict(DFOP_SFO, syn_biphasic_parms[i, ], - c(parent = 100, m1 = 0), sampling_times) - } -) -ds_biphasic <- lapply(ds_biphasic_mean, function(ds) { - add_err(ds, - sdfunc = function(value) sqrt(err_1$const^2 + value^2 * err_1$prop^2), - n = 1, secondary = "m1")[[1]] -}) - -test_that("Parent only models can be fitted with saemix", { - # Some fits were done in the setup script - mmkin_sfo_2 <- mmkin("SFO", ds_sfo, fixed_initials = c(parent = 100), quiet = TRUE) - - sfo_saemix_2 <- saem(mmkin_sfo_1, quiet = TRUE, transformations = "mkin") - sfo_saemix_3 <- expect_error(saem(mmkin_sfo_2, quiet = TRUE), "at least two parameters") - s_sfo_s1 <- summary(sfo_saemix_1) - s_sfo_s2 <- summary(sfo_saemix_2) - - sfo_nlme_1 <- expect_warning(nlme(mmkin_sfo_1), "not converge") - s_sfo_n <- summary(sfo_nlme_1) - - # Compare with input - expect_equal(round(s_sfo_s2$confint_ranef["SD.log_k_parent", "est."], 1), 0.3) - # k_parent is a bit different from input 0.03 here - expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), 0.035) - expect_equal(round(s_sfo_s2$confint_back["k_parent", "est."], 3), 0.035) - - # But the result is pretty unanimous between methods - expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), - round(s_sfo_s2$confint_back["k_parent", "est."], 3)) - expect_equal(round(s_sfo_s1$confint_back["k_parent", "est."], 3), - round(s_sfo_n$confint_back["k_parent", "est."], 3)) - - mmkin_dfop_1 <- mmkin("DFOP", ds_dfop, quiet = TRUE) - - dfop_saemix_1 <- saem(mmkin_dfop_1, quiet = TRUE, transformations = "mkin") - dfop_saemix_2 <- saem(mmkin_dfop_1, quiet = TRUE, transformations = "saemix") - dfop_nlme_1 <- nlme(mmkin_dfop_1) - s_dfop_s1 <- summary(dfop_saemix_1) - s_dfop_s2 <- summary(dfop_saemix_2) - s_dfop_n <- summary(dfop_nlme_1) - - dfop_pop <- as.numeric(dfop_pop) - expect_true(all(s_dfop_s1$confint_back[, "lower"] < dfop_pop)) - expect_true(all(s_dfop_s1$confint_back[, "upper"] > dfop_pop)) - expect_true(all(s_dfop_s2$confint_back[, "lower"] < dfop_pop)) - expect_true(all(s_dfop_s2$confint_back[, "upper"] > dfop_pop)) - - - # We get < 20% deviations with transformations made in mkin - rel_diff_1 <- (s_dfop_s1$confint_back[, "est."] - dfop_pop) / dfop_pop - expect_true(all(rel_diff_1 < 0.2)) - - # We get < 8% deviations with transformations made in saemix - rel_diff_2 <- (s_dfop_s2$confint_back[, "est."] - dfop_pop) / dfop_pop - expect_true(all(rel_diff_2 < 0.08)) -}) - -test_that("Print methods work", { - expect_known_output(print(sfo_saemix_1, digits = 1), "print_sfo_saemix_1.txt") - expect_known_output(print(mmkin_biphasic_mixed, digits = 2), "print_mmkin_biphasic_mixed.txt") -}) - -test_that("Saemix results are reproducible", { - - test_summary <- summary(saem_biphasic_s) - test_summary$saemixversion <- "Dummy 0.0 for testing" - test_summary$mkinversion <- "Dummy 0.0 for testing" - test_summary$Rversion <- "Dummy R version for testing" - test_summary$date.fit <- "Dummy date for testing" - test_summary$date.summary <- "Dummy date for testing" - test_summary$time <- c(elapsed = "test time 0") - - expect_known_output(print(test_summary, digits = 2), "summary_saem_biphasic_s.txt") - - dfop_sfo_pop <- as.numeric(dfop_sfo_pop) - ci_dfop_sfo_s_s <- summary(saem_biphasic_s)$confint_back - expect_true(all(ci_dfop_sfo_s_s[, "lower"] < dfop_sfo_pop)) - expect_true(all(ci_dfop_sfo_s_s[, "upper"] > dfop_sfo_pop)) - - # The following does not work, as k1 and k2 are not fitted well - ci_dfop_sfo_s_m <- summary(saem_biphasic_m)$confint_back - # expect_true(all(ci_dfop_sfo_s_m[, "lower"] < dfop_sfo_pop)) - # expect_true(all(ci_dfop_sfo_s_m[, "upper"] > dfop_sfo_pop)) - - # Somehow this does not work at the moment. But it took forever (~ 10 min) anyways... - #saem_biphasic_2 <- saem(mmkin_biphasic, solution_type = "deSolve", quiet = TRUE) - -}) -- cgit v1.2.1