From 0d8521f3f60082f0fd27da00a7ac8bcef9ee5ba0 Mon Sep 17 00:00:00 2001 From: Johannes Ranke Date: Wed, 26 Oct 2022 00:57:40 +0200 Subject: Make multistart work with testthat scopes Also skip long-running test with saem using the analytical from mkin --- R/multistart.R | 23 ++- log/test.log | 32 ++-- .../multistart/llhist-for-biphasic-saemix-fit.svg | 61 +++++++ .../multistart/parhist-for-biphasic-saemix-fit.svg | 196 +++++++++++++++++++++ tests/testthat/test_mixed.R | 1 - tests/testthat/test_multistart.R | 4 +- tests/testthat/test_saemix_parent.R | 2 +- 7 files changed, 301 insertions(+), 18 deletions(-) create mode 100644 tests/testthat/_snaps/multistart/llhist-for-biphasic-saemix-fit.svg create mode 100644 tests/testthat/_snaps/multistart/parhist-for-biphasic-saemix-fit.svg diff --git a/R/multistart.R b/R/multistart.R index 4282de9c..4f5ecde3 100644 --- a/R/multistart.R +++ b/R/multistart.R @@ -74,17 +74,34 @@ multistart.saem.mmkin <- function(object, n = 50, cores = 1, call <- match.call() if (n <= 1) stop("Please specify an n of at least 2") - mmkin_parms <- parms(object$mmkin, errparms = FALSE, + mmkin_object <- object$mmkin + + mmkin_parms <- parms(mmkin_object, errparms = FALSE, transformed = object$transformations == "mkin") start_parms <- apply( mmkin_parms, 1, function(x) stats::runif(n, min(x), max(x))) + saem_call <- object$call + saem_call[[1]] <- saem + saem_call[[2]] <- mmkin_object + i_startparms <- which(names(saem_call) == "degparms_start") + fit_function <- function(x) { - ret <- update(object, degparms_start = start_parms[x, ], ...) - ret$call[[4]] <- str2lang( + + new_startparms <- str2lang( paste0(capture.output(dput(start_parms[x, ])), collapse = "")) + + if (length(i_startparms) == 0) { + saem_call <- c(as.list(saem_call), degparms_start = new_startparms) + saem_call <- as.call(saem_call) + } else { + saem_call[i_startparms] <- new_startparms + } + + ret <- eval(saem_call) + return(ret) } diff --git a/log/test.log b/log/test.log index 84f81103..1e5dc943 100644 --- a/log/test.log +++ b/log/test.log @@ -1,25 +1,25 @@ ℹ Testing mkin ✔ | F W S OK | Context ✔ | 5 | AIC calculation -✔ | 5 | Analytical solutions for coupled models [3.2s] +✔ | 5 | Analytical solutions for coupled models [3.3s] ✔ | 5 | Calculation of Akaike weights ✔ | 3 | Export dataset for reading into CAKE -✔ | 12 | Confidence intervals and p-values [1.0s] -✔ | 1 12 | Dimethenamid data from 2018 [31.8s] +✔ | 12 | Confidence intervals and p-values [1.1s] +✔ | 1 12 | Dimethenamid data from 2018 [31.7s] ──────────────────────────────────────────────────────────────────────────────── Skip (test_dmta.R:98:3): Different backends get consistent results for SFO-SFO3+, dimethenamid data Reason: Fitting this ODE model with saemix takes about 15 minutes on my system ──────────────────────────────────────────────────────────────────────────────── -✔ | 14 | Error model fitting [4.8s] +✔ | 14 | Error model fitting [4.9s] ✔ | 5 | Time step normalisation ✔ | 4 | Calculation of FOCUS chi2 error levels [0.6s] ✔ | 14 | Results for FOCUS D established in expertise for UBA (Ranke 2014) [0.8s] ✔ | 4 | Test fitting the decline of metabolites from their maximum [0.4s] ✔ | 1 | Fitting the logistic model [0.2s] -✔ | 7 | Batch fitting and diagnosing hierarchical kinetic models [14.3s] +✔ | 7 | Batch fitting and diagnosing hierarchical kinetic models [14.0s] ✔ | 1 12 | Nonlinear mixed-effects models [0.3s] ──────────────────────────────────────────────────────────────────────────────── -Skip (test_mixed.R:68:3): saemix results are reproducible for biphasic fits +Skip (test_mixed.R:74:3): saemix results are reproducible for biphasic fits Reason: Fitting with saemix takes around 10 minutes when using deSolve ──────────────────────────────────────────────────────────────────────────────── ✔ | 3 | Test dataset classes mkinds and mkindsg @@ -27,11 +27,19 @@ Reason: Fitting with saemix takes around 10 minutes when using deSolve ✔ | 3 | mkinfit features [0.7s] ✔ | 8 | mkinmod model generation and printing [0.2s] ✔ | 3 | Model predictions with mkinpredict [0.3s] -✔ | 16 | Evaluations according to 2015 NAFTA guidance [1.7s] -✔ | 9 | Nonlinear mixed-effects models with nlme [8.3s] -✔ | 16 | Plotting [10.0s] +✔ | 2 3 | Multistart method for saem.mmkin models [17.7s] +──────────────────────────────────────────────────────────────────────────────── +Warning (test_multistart.R:15:3): multistart works for saem.mmkin models +Adding new file snapshot: 'tests/testhat/_snaps/llhist-for-biphasic-saemix-fit.svg' + +Warning (test_multistart.R:16:3): multistart works for saem.mmkin models +Adding new file snapshot: 'tests/testhat/_snaps/parhist-for-biphasic-saemix-fit.svg' +──────────────────────────────────────────────────────────────────────────────── +✔ | 16 | Evaluations according to 2015 NAFTA guidance [1.8s] +✔ | 9 | Nonlinear mixed-effects models with nlme [8.4s] +✔ | 16 | Plotting [10.1s] ✔ | 4 | Residuals extracted from mkinfit models -✔ | 36 | saemix parent models [308.7s] +✔ | 36 | saemix parent models [309.8s] ✔ | 2 | Complex test case from Schaefer et al. (2007) Piacenza paper [1.4s] ✔ | 11 | Processing of residue series ✔ | 7 | Fitting the SFORB model [3.6s] @@ -42,10 +50,10 @@ Reason: Fitting with saemix takes around 10 minutes when using deSolve ✔ | 4 | Calculation of maximum time weighted average concentrations (TWAs) [2.2s] ══ Results ═════════════════════════════════════════════════════════════════════ -Duration: 405.5 s +Duration: 424.4 s ── Skipped tests ────────────────────────────────────────────────────────────── • Fitting this ODE model with saemix takes about 15 minutes on my system (1) • Fitting with saemix takes around 10 minutes when using deSolve (1) -[ FAIL 0 | WARN 0 | SKIP 2 | PASS 254 ] +[ FAIL 0 | WARN 2 | SKIP 2 | PASS 257 ] diff --git a/tests/testthat/_snaps/multistart/llhist-for-biphasic-saemix-fit.svg b/tests/testthat/_snaps/multistart/llhist-for-biphasic-saemix-fit.svg new file mode 100644 index 00000000..154eb60d --- /dev/null +++ b/tests/testthat/_snaps/multistart/llhist-for-biphasic-saemix-fit.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + +Frequency of log likelihoods + + + + + + + +-1190 +-1185 +-1180 +-1175 +-1170 +-1165 + + + + +0 +1 +2 + + + + + + + + + + + + + + + + +original log likelihood +kernel density estimate + + diff --git a/tests/testthat/_snaps/multistart/parhist-for-biphasic-saemix-fit.svg b/tests/testthat/_snaps/multistart/parhist-for-biphasic-saemix-fit.svg new file mode 100644 index 00000000..aa2bc3d4 --- /dev/null +++ b/tests/testthat/_snaps/multistart/parhist-for-biphasic-saemix-fit.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +parent_0 +f_parent_to_m1 +k2 +g +a.1 +b.1 +SD.log_k_m1 +SD.log_k1 +SD.g_qlogis + + + + + +0.5 +1.0 +1.5 +2.0 +Normalised parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Starting parameters +Original run +Multistart runs + + diff --git a/tests/testthat/test_mixed.R b/tests/testthat/test_mixed.R index de030199..e005c982 100644 --- a/tests/testthat/test_mixed.R +++ b/tests/testthat/test_mixed.R @@ -24,7 +24,6 @@ test_that("nlme results are reproducible to some degree", { test_summary$date.summary <- "Dummy date for testing" test_summary$time <- c(elapsed = "test time 0") - print(test_summary, digits = 1) expect_known_output(print(test_summary, digits = 1), "summary_dfop_nlme_1.txt") # The biphasic example data illustrate that DFOP parameters are difficult to diff --git a/tests/testthat/test_multistart.R b/tests/testthat/test_multistart.R index 04f08aa7..e0b1ecd7 100644 --- a/tests/testthat/test_multistart.R +++ b/tests/testthat/test_multistart.R @@ -1,4 +1,6 @@ -test_that("multistart works for saem.mmix models", { +context("Multistart method for saem.mmkin models") + +test_that("multistart works for saem.mmkin models", { saem_biphasic_m_multi <- multistart(saem_biphasic_m, n = 8, cores = n_cores) expect_known_output(print(saem_biphasic_m_multi), diff --git a/tests/testthat/test_saemix_parent.R b/tests/testthat/test_saemix_parent.R index 4504e573..d8b6b19e 100644 --- a/tests/testthat/test_saemix_parent.R +++ b/tests/testthat/test_saemix_parent.R @@ -140,7 +140,7 @@ test_that("We can also use mkin solution methods for saem", { expect_error(saem(mmkin_dfop_1, quiet = TRUE, transformations = "saemix", solution_type = "analytical"), "saemix transformations is only supported if an analytical solution is implemented" ) - skip_on_cran() # This still takes almost 2.5 minutes although we do not solve ODEs + skip("This still takes almost 2.5 minutes although we do not solve ODEs") dfop_saemix_3 <- saem(mmkin_dfop_1, quiet = TRUE, transformations = "mkin", solution_type = "analytical", no_random_effect = "parent_0") distimes_dfop <- endpoints(dfop_saemix_1)$distimes -- cgit v1.2.1