From 478c6d5eec4c84b22b43adcbdf36888b302ead00 Mon Sep 17 00:00:00 2001 From: Johannes Ranke Date: Tue, 6 Dec 2022 10:33:24 +0100 Subject: Some parplot improvements llquant argument, improved legend text, tests --- NEWS.md | 2 + R/parplot.R | 16 +- log/test.log | 41 +++-- man/parplot.Rd | 7 +- .../_snaps/multistart/parplot-for-dfop-sfo-fit.svg | 169 ++++++++++----------- .../_snaps/multistart/parplot-for-sfo-fit.svg | 4 +- tests/testthat/test_multistart.R | 2 +- vignettes/FOCUS_D.html | 37 ++--- vignettes/FOCUS_L.html | 83 +++++----- 9 files changed, 183 insertions(+), 178 deletions(-) diff --git a/NEWS.md b/NEWS.md index 15c45cc9..c7929fbe 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ - 'R/summary.saem.mmkin.R': List all initial parameter values in the summary, including random effects and error model parameters. Avoid redundant warnings that occurred in the calculation of correlations of the fixed effects in the case that the Fisher information matrix could not be inverted. +- 'R/parplot.R': Possibility to select the top 'llquant' fraction of the fits for the parameter plots, and improved legend text. + # mkin 1.2.1 (2022-11-19) - '{data,R}/ds_mixed.rda': Include the test data in the package instead of generating it in 'tests/testthat/setup_script.R'. Refactor the generating code to make it consistent and update tests. diff --git a/R/parplot.R b/R/parplot.R index 98579779..63306ac2 100644 --- a/R/parplot.R +++ b/R/parplot.R @@ -10,7 +10,10 @@ #' #' @param object The [multistart] object #' @param llmin The minimum likelihood of objects to be shown -#' @param scale By default, scale parameters using the best available fit. +#' @param llquant Fractional value for selecting only the fits with higher +#' likelihoods. Overrides 'llmin'. +#' @param scale By default, scale parameters using the best +#' available fit. #' If 'median', parameters are scaled using the median parameters from all fits. #' @param main Title of the plot #' @param lpos Positioning of the legend. @@ -28,7 +31,8 @@ parplot <- function(object, ...) { #' @rdname parplot #' @export -parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, scale = c("best", "median"), +parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, llquant = NA, + scale = c("best", "median"), lpos = "bottomleft", main = "", ...) { oldpar <- par(no.readonly = TRUE) @@ -48,6 +52,10 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, scale = c("best" stop("parplot is only implemented for multistart.saem.mmkin objects") } ll <- sapply(object, llfunc) + if (!is.na(llquant[1])) { + if (llmin != -Inf) warning("Overriding 'llmin' because 'llquant' was specified") + llmin <- quantile(ll, 1 - llquant) + } selected <- which(ll > llmin) selected_parms <- all_parms[selected, ] @@ -110,7 +118,7 @@ parplot.multistart.saem.mmkin <- function(object, llmin = -Inf, scale = c("best" legend(lpos, inset = c(0.05, 0.05), bty = "n", pch = 1, col = 3:1, lty = c(NA, NA, 1), legend = c( - "Starting parameters", - "Original run", + "Original start", + "Original results", "Multistart runs")) } diff --git a/log/test.log b/log/test.log index 5764f209..7614b136 100644 --- a/log/test.log +++ b/log/test.log @@ -1,22 +1,22 @@ ℹ Testing mkin ✔ | F W S OK | Context ✔ | 5 | AIC calculation -✔ | 5 | Analytical solutions for coupled models [3.3s] +✔ | 5 | Analytical solutions for coupled models [3.2s] ✔ | 5 | Calculation of Akaike weights ✔ | 3 | Export dataset for reading into CAKE ✔ | 12 | Confidence intervals and p-values [1.1s] -✔ | 1 12 | Dimethenamid data from 2018 [31.9s] +✔ | 1 12 | Dimethenamid data from 2018 [32.0s] ──────────────────────────────────────────────────────────────────────────────── Skip ('test_dmta.R:98'): 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.9s] +✔ | 14 | Error model fitting [4.8s] ✔ | 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.3s] ✔ | 1 | Fitting the logistic model [0.2s] -✔ | 10 | Batch fitting and diagnosing hierarchical kinetic models [41.4s] +✔ | 10 | Batch fitting and diagnosing hierarchical kinetic models [42.2s] ✔ | 1 11 | Nonlinear mixed-effects models [13.3s] ──────────────────────────────────────────────────────────────────────────────── Skip ('test_mixed.R:78'): saemix results are reproducible for biphasic fits @@ -26,32 +26,41 @@ Reason: Fitting with saemix takes around 10 minutes when using deSolve ✔ | 10 | Special cases of mkinfit calls [0.6s] ✔ | 3 | mkinfit features [0.7s] ✔ | 8 | mkinmod model generation and printing [0.2s] -✔ | 3 | Model predictions with mkinpredict [0.3s] -✔ | 12 | Multistart method for saem.mmkin models [47.5s] -✔ | 16 | Evaluations according to 2015 NAFTA guidance [2.3s] -✔ | 9 | Nonlinear mixed-effects models with nlme [9.5s] -✔ | 15 | Plotting [10.2s] +✔ | 3 | Model predictions with mkinpredict [0.4s] +✖ | 1 11 | Multistart method for saem.mmkin models [46.7s] +──────────────────────────────────────────────────────────────────────────────── +Failure ('test_multistart.R:56'): multistart works for saem.mmkin models +Snapshot of `testcase` to 'multistart/parplot-for-dfop-sfo-fit.svg' has changed +Run `testthat::snapshot_review('multistart/')` to review changes +Backtrace: + 1. vdiffr::expect_doppelganger("parplot for dfop sfo fit", parplot_dfop_sfo) + at test_multistart.R:56:2 + 3. testthat::expect_snapshot_file(...) +──────────────────────────────────────────────────────────────────────────────── +✔ | 16 | Evaluations according to 2015 NAFTA guidance [2.2s] +✔ | 9 | Nonlinear mixed-effects models with nlme [9.4s] +✔ | 15 | Plotting [10.1s] ✔ | 4 | Residuals extracted from mkinfit models -✔ | 1 36 | saemix parent models [73.0s] +✔ | 1 36 | saemix parent models [73.6s] ──────────────────────────────────────────────────────────────────────────────── Skip ('test_saemix_parent.R:143'): We can also use mkin solution methods for saem Reason: This still takes almost 2.5 minutes although we do not solve ODEs ──────────────────────────────────────────────────────────────────────────────── -✔ | 2 | Complex test case from Schaefer et al. (2007) Piacenza paper [1.5s] +✔ | 2 | Complex test case from Schaefer et al. (2007) Piacenza paper [1.4s] ✔ | 11 | Processing of residue series -✔ | 10 | Fitting the SFORB model [3.9s] +✔ | 10 | Fitting the SFORB model [3.7s] ✔ | 1 | Summaries of old mkinfit objects ✔ | 5 | Summary [0.2s] -✔ | 4 | Results for synthetic data established in expertise for UBA (Ranke 2014) [2.2s] -✔ | 9 | Hypothesis tests [8.4s] +✔ | 4 | Results for synthetic data established in expertise for UBA (Ranke 2014) [2.3s] +✔ | 9 | Hypothesis tests [8.1s] ✔ | 4 | Calculation of maximum time weighted average concentrations (TWAs) [2.2s] ══ Results ═════════════════════════════════════════════════════════════════════ -Duration: 261.1 s +Duration: 260.9 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) • This still takes almost 2.5 minutes although we do not solve ODEs (1) -[ FAIL 0 | WARN 0 | SKIP 3 | PASS 270 ] +[ FAIL 1 | WARN 0 | SKIP 3 | PASS 269 ] diff --git a/man/parplot.Rd b/man/parplot.Rd index ac9e02cf..67bf0cc1 100644 --- a/man/parplot.Rd +++ b/man/parplot.Rd @@ -10,6 +10,7 @@ parplot(object, ...) \method{parplot}{multistart.saem.mmkin}( object, llmin = -Inf, + llquant = NA, scale = c("best", "median"), lpos = "bottomleft", main = "", @@ -23,7 +24,11 @@ parplot(object, ...) \item{llmin}{The minimum likelihood of objects to be shown} -\item{scale}{By default, scale parameters using the best available fit. +\item{llquant}{Fractional value for selecting only the fits with higher +likelihoods. Overrides 'llmin'.} + +\item{scale}{By default, scale parameters using the best +available fit. If 'median', parameters are scaled using the median parameters from all fits.} \item{lpos}{Positioning of the legend.} diff --git a/tests/testthat/_snaps/multistart/parplot-for-dfop-sfo-fit.svg b/tests/testthat/_snaps/multistart/parplot-for-dfop-sfo-fit.svg index 7017908e..b01dac74 100644 --- a/tests/testthat/_snaps/multistart/parplot-for-dfop-sfo-fit.svg +++ b/tests/testthat/_snaps/multistart/parplot-for-dfop-sfo-fit.svg @@ -25,109 +25,104 @@ - - - - + + + + - - - - - - - - + + + + + + - - - - - + + + + + - + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - + + + + + - + @@ -194,8 +189,8 @@ -Starting parameters -Original run +Original start +Original results Multistart runs diff --git a/tests/testthat/_snaps/multistart/parplot-for-sfo-fit.svg b/tests/testthat/_snaps/multistart/parplot-for-sfo-fit.svg index a47a585a..c8d4970b 100644 --- a/tests/testthat/_snaps/multistart/parplot-for-sfo-fit.svg +++ b/tests/testthat/_snaps/multistart/parplot-for-sfo-fit.svg @@ -103,8 +103,8 @@ -Starting parameters -Original run +Original start +Original results Multistart runs diff --git a/tests/testthat/test_multistart.R b/tests/testthat/test_multistart.R index 91ef71f0..dda0ea23 100644 --- a/tests/testthat/test_multistart.R +++ b/tests/testthat/test_multistart.R @@ -50,7 +50,7 @@ test_that("multistart works for saem.mmkin models", { llhist_dfop_sfo <- function() llhist(saem_dfop_sfo_m_multi) parplot_dfop_sfo <- function() parplot(saem_dfop_sfo_m_multi, - ylim = c(0.5, 2)) + ylim = c(0.5, 2), llquant = 0.5) vdiffr::expect_doppelganger("llhist for dfop sfo fit", llhist_dfop_sfo) vdiffr::expect_doppelganger("parplot for dfop sfo fit", parplot_dfop_sfo) diff --git a/vignettes/FOCUS_D.html b/vignettes/FOCUS_D.html index 9f768b06..b8a63a7b 100644 --- a/vignettes/FOCUS_D.html +++ b/vignettes/FOCUS_D.html @@ -299,8 +299,8 @@ pre code { border-radius: 4px; } -.tabset-dropdown > .nav-tabs > li.active:before { - content: ""; +.tabset-dropdown > .nav-tabs > li.active:before, .tabset-dropdown > .nav-tabs.nav-tabs-open:before { + content: "\e259"; font-family: 'Glyphicons Halflings'; display: inline-block; padding: 10px; @@ -308,16 +308,9 @@ pre code { } .tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before { - content: ""; - border: none; -} - -.tabset-dropdown > .nav-tabs.nav-tabs-open:before { - content: ""; + content: "\e258"; font-family: 'Glyphicons Halflings'; - display: inline-block; - padding: 10px; - border-right: 1px solid #ddd; + border: none; } .tabset-dropdown > .nav-tabs > li.active { @@ -364,7 +357,7 @@ pre code {

Example evaluation of FOCUS Example Dataset D

Johannes Ranke

-

Last change 31 January 2019 (rebuilt 2022-07-08)

+

Last change 31 January 2019 (rebuilt 2022-12-06)

@@ -438,10 +431,10 @@ print(FOCUS_2006_D)

A comprehensive report of the results is obtained using the summary method for mkinfit objects.

summary(fit)
-
## mkin version used for fitting:    1.1.0 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Fri Jul  8 15:44:37 2022 
-## Date of summary: Fri Jul  8 15:44:38 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:42 2022 
+## Date of summary: Tue Dec  6 09:39:42 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - k_parent * parent
@@ -449,7 +442,7 @@ print(FOCUS_2006_D)
## ## Model predictions using solution type analytical ## -## Fitted using 401 model solutions performed in 0.13 s +## Fitted using 401 model solutions performed in 0.158 s ## ## Error model: Constant variance ## @@ -492,11 +485,11 @@ print(FOCUS_2006_D)
## ## Parameter correlation: ## parent_0 log_k_parent log_k_m1 f_parent_qlogis sigma -## parent_0 1.000e+00 5.174e-01 -1.688e-01 -5.471e-01 -1.174e-06 -## log_k_parent 5.174e-01 1.000e+00 -3.263e-01 -5.426e-01 -8.492e-07 -## log_k_m1 -1.688e-01 -3.263e-01 1.000e+00 7.478e-01 8.220e-07 -## f_parent_qlogis -5.471e-01 -5.426e-01 7.478e-01 1.000e+00 1.307e-06 -## sigma -1.174e-06 -8.492e-07 8.220e-07 1.307e-06 1.000e+00 +## parent_0 1.000e+00 5.174e-01 -1.688e-01 -5.471e-01 -1.172e-06 +## log_k_parent 5.174e-01 1.000e+00 -3.263e-01 -5.426e-01 -8.483e-07 +## log_k_m1 -1.688e-01 -3.263e-01 1.000e+00 7.478e-01 8.205e-07 +## f_parent_qlogis -5.471e-01 -5.426e-01 7.478e-01 1.000e+00 1.305e-06 +## sigma -1.172e-06 -8.483e-07 8.205e-07 1.305e-06 1.000e+00 ## ## Backtransformed parameters: ## Confidence intervals for internally transformed parameters are asymmetric. diff --git a/vignettes/FOCUS_L.html b/vignettes/FOCUS_L.html index da6c11fe..b8c9ba0c 100644 --- a/vignettes/FOCUS_L.html +++ b/vignettes/FOCUS_L.html @@ -1373,8 +1373,8 @@ pre code { border-radius: 4px; } -.tabset-dropdown > .nav-tabs > li.active:before { - content: ""; +.tabset-dropdown > .nav-tabs > li.active:before, .tabset-dropdown > .nav-tabs.nav-tabs-open:before { + content: "\e259"; font-family: 'Glyphicons Halflings'; display: inline-block; padding: 10px; @@ -1382,16 +1382,9 @@ pre code { } .tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before { - content: ""; - border: none; -} - -.tabset-dropdown > .nav-tabs.nav-tabs-open:before { - content: ""; + content: "\e258"; font-family: 'Glyphicons Halflings'; - display: inline-block; - padding: 10px; - border-right: 1px solid #ddd; + border: none; } .tabset-dropdown > .nav-tabs > li.active { @@ -1517,7 +1510,7 @@ div.tocify {

Example evaluation of FOCUS Laboratory Data L1 to L3

Johannes Ranke

-

Last change 18 May 2022 (rebuilt 2022-09-14)

+

Last change 18 May 2022 (rebuilt 2022-12-06)

@@ -1536,17 +1529,17 @@ FOCUS_2006_L1_mkin <- mkin_wide_to_long(FOCUS_2006_L1)

Since mkin version 0.9-32 (July 2014), we can use shorthand notation like "SFO" for parent only degradation models. The following two lines fit the model and produce the summary report of the model fit. This covers the numerical analysis given in the FOCUS report.

m.L1.SFO <- mkinfit("SFO", FOCUS_2006_L1_mkin, quiet = TRUE)
 summary(m.L1.SFO)
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:35 2022 
-## Date of summary: Wed Sep 14 22:28:35 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:45 2022 
+## Date of summary: Tue Dec  6 09:39:45 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - k_parent * parent
 ## 
 ## Model predictions using solution type analytical 
 ## 
-## Fitted using 133 model solutions performed in 0.032 s
+## Fitted using 133 model solutions performed in 0.033 s
 ## 
 ## Error model: Constant variance 
 ## 
@@ -1637,10 +1630,10 @@ summary(m.L1.SFO)
## Warning in sqrt(1/diag(V)): NaNs produced
## Warning in cov2cor(ans$covar): diag(.) had 0 or NA entries; non-finite result is
 ## doubtful
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:35 2022 
-## Date of summary: Wed Sep 14 22:28:35 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:45 2022 
+## Date of summary: Tue Dec  6 09:39:45 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - (alpha/beta) * 1/((time/beta) + 1) * parent
@@ -1742,17 +1735,17 @@ plot(m.L2.FOMC, show_residuals = TRUE,
      main = "FOCUS L2 - FOMC")

summary(m.L2.FOMC, data = FALSE)
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:35 2022 
-## Date of summary: Wed Sep 14 22:28:35 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:45 2022 
+## Date of summary: Tue Dec  6 09:39:45 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - (alpha/beta) * 1/((time/beta) + 1) * parent
 ## 
 ## Model predictions using solution type analytical 
 ## 
-## Fitted using 239 model solutions performed in 0.049 s
+## Fitted using 239 model solutions performed in 0.048 s
 ## 
 ## Error model: Constant variance 
 ## 
@@ -1820,10 +1813,10 @@ plot(m.L2.DFOP, show_residuals = TRUE, show_errmin = TRUE,
      main = "FOCUS L2 - DFOP")

summary(m.L2.DFOP, data = FALSE)
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:36 2022 
-## Date of summary: Wed Sep 14 22:28:36 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:46 2022 
+## Date of summary: Tue Dec  6 09:39:46 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - ((k1 * g * exp(-k1 * time) + k2 * (1 - g) * exp(-k2 *
@@ -1832,7 +1825,7 @@ plot(m.L2.DFOP, show_residuals = TRUE, show_errmin = TRUE,
 ## 
 ## Model predictions using solution type analytical 
 ## 
-## Fitted using 581 model solutions performed in 0.135 s
+## Fitted using 581 model solutions performed in 0.131 s
 ## 
 ## Error model: Constant variance 
 ## 
@@ -1920,10 +1913,10 @@ plot(mm.L3)

The objects returned by mmkin are arranged like a matrix, with models as a row index and datasets as a column index.

We can extract the summary and plot for e.g. the DFOP fit, using square brackets for indexing which will result in the use of the summary and plot functions working on mkinfit objects.

summary(mm.L3[["DFOP", 1]])
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:36 2022 
-## Date of summary: Wed Sep 14 22:28:36 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:46 2022 
+## Date of summary: Tue Dec  6 09:39:46 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - ((k1 * g * exp(-k1 * time) + k2 * (1 - g) * exp(-k2 *
@@ -1932,7 +1925,7 @@ plot(mm.L3)
## ## Model predictions using solution type analytical ## -## Fitted using 376 model solutions performed in 0.081 s +## Fitted using 376 model solutions performed in 0.078 s ## ## Error model: Constant variance ## @@ -2028,17 +2021,17 @@ plot(mm.L4)

The χ2 error level of 3.3% as well as the plot suggest that the SFO model fits very well. The error level at which the χ2 test passes is slightly lower for the FOMC model. However, the difference appears negligible.

summary(mm.L4[["SFO", 1]], data = FALSE)
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:36 2022 
-## Date of summary: Wed Sep 14 22:28:37 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:47 2022 
+## Date of summary: Tue Dec  6 09:39:47 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - k_parent * parent
 ## 
 ## Model predictions using solution type analytical 
 ## 
-## Fitted using 142 model solutions performed in 0.034 s
+## Fitted using 142 model solutions performed in 0.03 s
 ## 
 ## Error model: Constant variance 
 ## 
@@ -2092,10 +2085,10 @@ plot(mm.L4)
## DT50 DT90 ## parent 106 352
summary(mm.L4[["FOMC", 1]], data = FALSE)
-
## mkin version used for fitting:    1.1.2 
-## R version used for fitting:       4.2.1 
-## Date of fit:     Wed Sep 14 22:28:37 2022 
-## Date of summary: Wed Sep 14 22:28:37 2022 
+
## mkin version used for fitting:    1.2.2 
+## R version used for fitting:       4.2.2 
+## Date of fit:     Tue Dec  6 09:39:47 2022 
+## Date of summary: Tue Dec  6 09:39:47 2022 
 ## 
 ## Equations:
 ## d_parent/dt = - (alpha/beta) * 1/((time/beta) + 1) * parent
-- 
cgit v1.2.1