diff --git a/.Rbuildignore b/.Rbuildignore index 3378f28..2b51e2b 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -2,5 +2,7 @@ ^README\.Rmd$ ^bad-library.md$ ^pkgdown$ +^_pkgdown.yml$ ^.github$ ^vignettes/articles$ +^cran-comments\.md$ diff --git a/DESCRIPTION b/DESCRIPTION index 2e878e1..a3b87f2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: monolix2rx Title: 'monolix2rx' Converts 'Monolix' Models to 'rxode2' -Version: 0.0.0.9000 +Version: 0.0.1 Authors@R: c(person("Matthew","Fidler", role = c("aut", "cre"), email = "matthew.fidler@gmail.com", comment=c(ORCID="0000-0001-8538-6691")), person("Justin", "Wilkins", role = "ctb", email = "justin.wilkins@occams.com", comment=c(ORCID="0000-0002-7099-9396"))) @@ -40,7 +40,7 @@ Imports: crayon, lotri, magrittr, - rxode2 (> 2.0.13), + rxode2 (>= 3.0.0), Suggests: devtools, testthat (>= 3.0.0), diff --git a/NAMESPACE b/NAMESPACE index 99c7cff..b11b395 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -69,13 +69,8 @@ export(logit) export(lotri) export(mlxTxt) export(mlxtran) -export(mlxtranGetMutate) export(model) export(monolix2rx) -export(monolixDataImport) -export(monolixEndpoints) -export(monolixEtaImport) -export(monolixPredIpred) export(rxRename) export(rxSolve) export(rxUiGet) diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..80bfec9 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,3 @@ +# monolix2rx 0.0.1 + +* Initial CRAN submission. diff --git a/R/dataCov.R b/R/dataCov.R index cc87b37..7e50e4e 100644 --- a/R/dataCov.R +++ b/R/dataCov.R @@ -3,7 +3,7 @@ #' #' @param mlxtran input mlxtran file #' @return mlxtran string that can be applied to a model (by evaluating it) -#' @export +#' @noRd #' @author Matthew L. Fidler #' @examples #' diff --git a/R/dataImport.R b/R/dataImport.R index 558e051..32f20f4 100644 --- a/R/dataImport.R +++ b/R/dataImport.R @@ -211,7 +211,7 @@ #' @inheritParams utils::read.table #' @return Dataset appropriate for using with the rxode2 model for #' simulations -#' @export +#' @noRd #' @author Matthew L. Fidler #' @examples #' diff --git a/R/endpointInfo.R b/R/endpointInfo.R index 9127fd2..5d39787 100644 --- a/R/endpointInfo.R +++ b/R/endpointInfo.R @@ -4,7 +4,7 @@ #' @param mlxtran This is the parsed mlxtran or imported rxode2 model from monolix #' #' @return nothing, called for side effects -#' @export +#' @noRd #' @author Matthew L. Fidler monolixEndpoints <- function(mlxtran) { mlxtran <- .monolixGetMlxtran(mlxtran) diff --git a/R/etaImport.R b/R/etaImport.R index c9f0219..c43bdf7 100644 --- a/R/etaImport.R +++ b/R/etaImport.R @@ -3,7 +3,7 @@ #' @param mlxtran mlxtran file where data input is specified #' @inheritParams utils::read.table #' @author Matthew L Fidler -#' @export +#' @noRd monolixEtaImport <- function(mlxtran, na.strings=c("NA", ".")) { mlxtran <- .monolixGetMlxtran(mlxtran) if (is.null(mlxtran)) return(NULL) diff --git a/R/indDef.R b/R/indDef.R index 61bf042..82c3487 100644 --- a/R/indDef.R +++ b/R/indDef.R @@ -156,13 +156,7 @@ return(.c) }) .ret$cov <- .monolix2rx$cov - .ret$coef <- lapply(seq_along(.coef), - function(i) { - .cur <- .coef[[i]] - .w <- which(grepl("^rxCov_", .cur)) - if (length(.w) >= 1) .cur <- .cur[-.w] - .cur - }) + .ret$coef <- .coef .rx <- paste0(.rx, " + ", paste(vapply(seq_along(.ret$coef), function(i) { @@ -184,10 +178,20 @@ .coef[.w]) .coef <- .coef[-.w] .ref <- .ref[-.w] + .w <- which(grepl("^rxCov_", .coef)) + if (length(.w) > 0) { + .coef <- .coef[-.w] + .ref <- .ref[-.w] + } return(paste(paste0(.coef, " * (", .cov, " == '", .ref, "')"), collapse=" + ")) } - } - paste(paste0(.ret$coef[[i]], "*", .ret$cov[i]), collapse=" + ") + } + .coef <- .ret$coef[[i]] + .w <- which(grepl("^rxCov_", .coef)) + if (length(.w) > 0) { + .coef <- .coef[-.w] + } + paste(paste0(.coef, "*", .ret$cov[i]), collapse=" + ") }, character(1), USE.NAMES=FALSE), collapse=" + ")) } diff --git a/R/ipredImport.R b/R/ipredImport.R index e1b8078..156ebe0 100644 --- a/R/ipredImport.R +++ b/R/ipredImport.R @@ -53,7 +53,7 @@ #' @param mlxtran mlxtran file where data input is specified #' @inheritParams utils::read.table #' @author Matthew L Fidler -#' @export +#' @noRd monolixPredIpred <- function(mlxtran, na.strings=c("NA", ".")) { mlxtran <- .monolixGetMlxtran(mlxtran) withr::with_dir(.monolixGetPwd(mlxtran), { diff --git a/R/rxSolve.R b/R/rxSolve.R index 5d6eb09..12b37ed 100644 --- a/R/rxSolve.R +++ b/R/rxSolve.R @@ -6,7 +6,7 @@ rxSolve.monolix2rx <- function(object, params = NULL, events = NULL, maxsteps = 70000L, hmin = 0, hmax = NA_real_, hmaxSd = 0, hini = 0, maxordn = 12L, maxords = 5L, ..., cores, covsInterpolation = c("locf", "linear", "nocb", "midpoint"), naInterpolation = c("locf", - "nocb"), keepInterpolation = c("locf", "nocb", "na"), + "nocb"), keepInterpolation = c("na", "locf", "nocb"), addCov = TRUE, sigma = NULL, sigmaDf = NULL, sigmaLower = -Inf, sigmaUpper = Inf, nCoresRV = 1L, sigmaIsChol = FALSE, sigmaSeparation = c("auto", "lkj", "separation"), sigmaXform = c("identity", "variance", diff --git a/R/validate.R b/R/validate.R index b9e3e03..6fd7a17 100644 --- a/R/validate.R +++ b/R/validate.R @@ -180,9 +180,22 @@ .qai <- stats::quantile(with(.both, abs(ipred-monolixIpred)), .q, na.rm=TRUE) .qp <- stats::quantile(with(.both, 100*abs((pred-monolixPred)/monolixIpred)), .q, na.rm=TRUE) .qap <- stats::quantile(with(.both, abs(pred-monolixPred)), .q, na.rm=TRUE) + .qw <- stats::quantile(with(.both, 100*abs((iwres-monolixIwres)/monolixIwres)), .q, na.rm=TRUE) .qaw <- stats::quantile(with(.both, abs(iwres-monolixIwres)), .q, na.rm=TRUE) + .ui$ipredAtol <- .qai[3] + .ui$ipredRtol <- .qi[3]/100 + .ui$ipredCompare <- .both[,grepl("(id|time|monolixIpred|ipred|cmt)", names(.both), ignore.case=TRUE)] + + .ui$predAtol <- .qap[3] + .ui$predRtol <- .qp[3]/100 + .ui$predCompare <- .both[,grepl("^(id|time|monolixPred|pred|cmt)$", names(.both), ignore.case=TRUE)] + + .ui$iwresAtol <- .qaw[3] + .ui$iwresRtol <- .qw[3]/100 + .ui$iwresCompare <- .both[,grepl("(id|time|monolixIwres|iwres|cmt)", names(.both), ignore.case=TRUE)] + .msg <- c(paste0("ipred relative difference compared to Monolix ipred: ", round(.qi[3], 2), "%; ", .ci0 * 100,"% percentile: (", round(.qi[2], 2), "%,", round(.qi[4], 2), "%); rtol=", diff --git a/README.Rmd b/README.Rmd index 8a44e1d..4487bae 100644 --- a/README.Rmd +++ b/README.Rmd @@ -41,6 +41,37 @@ You can install the development version of monolix2rx from # install.packages("devtools") devtools::install_github("nlmixr2/monolix2rx") ``` +## What you can do with `monolix2rx`/`babelmixr2` + +You can do many useful tasks directly converting between nlmixr2 and +NONMEM models; you can: + +- [Convert a Monolix model to a rxode2/nlmixr2 model](https://nlmixr2.github.io/monolix2rx/articles/convert-nlmixr2.html) + +Then with nlmixr2 fit models and monolix2rx models coming from both conversions, you can: + +- [Perform simulations of new + dosing](https://nlmixr2.github.io/monolix2rx/articles/simulate-new-dosing.html) from the Monolix model or even [simulate using the uncertainty in your model to simulate new scenarios](https://nlmixr2.github.io/monolix2rx/articles/simulate-uncertainty.html) + +- [Modify the model to calculate derived parameters](https://nlmixr2.github.io/monolix2rx/articles/simulate-extra-items.html) (like AUC). These parameters slow down Monolix’s optimization, but can help in your simulation scenario. + +- [Simulating with Covariates/Input PK + parameters](https://nlmixr2.github.io/monolix2rx/articles/simulate-new-dosing-with-covs.html). This example shows approaches to resample from the input dataset for covariate selection. + +With nonmem2rx and babelmixr2, convert the imported rxode2 model to a nlmixr2 object, allowing: + +- [Generation of Word and PowerPoint plots with + nlmixr2rpt](https://nlmixr2.github.io/monolix2rx/articles/create-office.html) + +- [Easy VPC + creation](https://nlmixr2.github.io/monolix2rx/articles/create-vpc.html) + (with `vpcPlot()`) + +- [Easy Individual plots with extra solved + points](https://nlmixr2.github.io/monolix2rx/articles/create-augPred.html). This + will show the curvature of individual and population fits for + sparse data-sets (with `augPred()`) + ## Example diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..565e1f8 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,44 @@ +url: ~ +template: + bootstrap: 5 + params: + bootswatch: flatly +reference: + - title: Importing Monolix to rxode2 + contents: + - monolix2rx + - title: Reading in `mlxtran` + contents: + - mlxtran + - mlxTxt +navbar: + left: + - text: Converting + icon: fa-arrow-right + href: articles/convert-nlmixr2.html + - text: "Qualify" + icon: fa-check + href: articles/rxode2-validate.html + - text: "Simulation" + icon: fa-dice + menu: + - text: "New Dosing Scenarios" + href: articles/simulate-new-dosing.html + - text: "Simulating with Uncertainty" + href: articles/simulate-uncertainty.html + - text: "Simulating with Derived Variables" + href: articles/simulate-extra-items.html + - text: "Reporting" + menu: + - text: "Creating word and powerpoint documents" + href: articles/create-office.html + - text: "Easily create VPC plots" + href: articles/create-vpc.html + - text: "Create enriched Individual plots" + href: articles/create-augPred.html + - text: "Functions" + icon: fa-file-code-o + href: reference/index.html + - text: "News" + icon: fas fa-rss + href: news/index.html diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 0000000..d944842 --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,8 @@ + +This adds monolix import to the nlmixr2 ecosystem + +## R CMD check results + +0 errors | 0 warnings | 1 note + +* This is a new release. diff --git a/man/mlxtranGetMutate.Rd b/man/mlxtranGetMutate.Rd deleted file mode 100644 index feaf1c3..0000000 --- a/man/mlxtranGetMutate.Rd +++ /dev/null @@ -1,28 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dataCov.R -\name{mlxtranGetMutate} -\alias{mlxtranGetMutate} -\title{Get the string of the mutate statement for input dataset based on -mlxtran} -\usage{ -mlxtranGetMutate(mlxtran) -} -\arguments{ -\item{mlxtran}{input mlxtran file} -} -\value{ -mlxtran string that can be applied to a model (by evaluating it) -} -\description{ -Get the string of the mutate statement for input dataset based on -mlxtran -} -\examples{ - -covD <- system.file("cov", package="monolix2rx") -m <- mlxtran(file.path(covD, "phenobarbital_project.mlxtran")) -message(mlxtranGetMutate(m)) -} -\author{ -Matthew L. Fidler -} diff --git a/man/monolixDataImport.Rd b/man/monolixDataImport.Rd deleted file mode 100644 index caefe38..0000000 --- a/man/monolixDataImport.Rd +++ /dev/null @@ -1,52 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dataImport.R -\name{monolixDataImport} -\alias{monolixDataImport} -\title{Import a dataset from monolix (based on an imported model)} -\usage{ -monolixDataImport(ui, data, na.strings = c("NA", ".")) -} -\arguments{ -\item{ui}{A rxode2 ui model imported from monolix} - -\item{data}{dataset to convert to nlmixr2 format; if the dataset is -missing, load from the mlxtran specification} - -\item{na.strings}{a character vector of strings which are to be - interpreted as \code{\link{NA}} values. Blank fields are also - considered to be missing values in logical, integer, numeric and - complex fields. Note that the test happens \emph{after} - white space is stripped from the input (if enabled), so \code{na.strings} - values may need their own white space stripped in advance.} -} -\value{ -Dataset appropriate for using with the rxode2 model for -simulations -} -\description{ -Import a dataset from monolix (based on an imported model) -} -\examples{ - -# First load in the model; in this case the theo model -# This is modified from the Monolix demos by saving the model -# File as a text file (hence you can access without model library) -# setup. -# -# This example is also included in the monolix2rx package, so -# you refer to the location with `system.file()`: - -pkgTheo <- system.file("theo", package="monolix2rx") - -mod <- monolix2rx(file.path(pkgTheo, "theophylline_project.mlxtran")) - -# read in monolix dataset - -dat <- read.table(file.path(pkgTheo, "data", "theophylline_data.txt"),na=".", header=TRUE) - -monolixDataImport(mod, dat) - -} -\author{ -Matthew L. Fidler -} diff --git a/man/monolixEndpoints.Rd b/man/monolixEndpoints.Rd deleted file mode 100644 index 6753bf9..0000000 --- a/man/monolixEndpoints.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/endpointInfo.R -\name{monolixEndpoints} -\alias{monolixEndpoints} -\title{This gets the monolix endpoint information in the model} -\usage{ -monolixEndpoints(mlxtran) -} -\arguments{ -\item{mlxtran}{This is the parsed mlxtran or imported rxode2 model from monolix} -} -\value{ -nothing, called for side effects -} -\description{ -This gets the monolix endpoint information in the model -} -\author{ -Matthew L. Fidler -} diff --git a/man/monolixEtaImport.Rd b/man/monolixEtaImport.Rd deleted file mode 100644 index 3cdd6ca..0000000 --- a/man/monolixEtaImport.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/etaImport.R -\name{monolixEtaImport} -\alias{monolixEtaImport} -\title{Load data from a mlxtran defined dataset} -\usage{ -monolixEtaImport(mlxtran, na.strings = c("NA", ".")) -} -\arguments{ -\item{mlxtran}{mlxtran file where data input is specified} - -\item{na.strings}{a character vector of strings which are to be - interpreted as \code{\link{NA}} values. Blank fields are also - considered to be missing values in logical, integer, numeric and - complex fields. Note that the test happens \emph{after} - white space is stripped from the input (if enabled), so \code{na.strings} - values may need their own white space stripped in advance.} -} -\description{ -Load data from a mlxtran defined dataset -} -\author{ -Matthew L Fidler -} diff --git a/man/monolixPredIpred.Rd b/man/monolixPredIpred.Rd deleted file mode 100644 index 49c9ec0..0000000 --- a/man/monolixPredIpred.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ipredImport.R -\name{monolixPredIpred} -\alias{monolixPredIpred} -\title{Load ipred/pred from a monolix run} -\usage{ -monolixPredIpred(mlxtran, na.strings = c("NA", ".")) -} -\arguments{ -\item{mlxtran}{mlxtran file where data input is specified} - -\item{na.strings}{a character vector of strings which are to be - interpreted as \code{\link{NA}} values. Blank fields are also - considered to be missing values in logical, integer, numeric and - complex fields. Note that the test happens \emph{after} - white space is stripped from the input (if enabled), so \code{na.strings} - values may need their own white space stripped in advance.} -} -\description{ -Load ipred/pred from a monolix run -} -\author{ -Matthew L Fidler -} diff --git a/vignettes/articles/convert-nlmixr2.Rmd b/vignettes/articles/convert-nlmixr2.Rmd index 4fa1f13..b977fde 100644 --- a/vignettes/articles/convert-nlmixr2.Rmd +++ b/vignettes/articles/convert-nlmixr2.Rmd @@ -20,8 +20,7 @@ efficiently to the nlmixr2 residual syntax. ## Example ```{r asNonmem2Rx} -library(monolix2rx) -library(babelmixr2) +library(babelmixr2) # will re-export much of monolix2rx # You use the path to the monolix mlxtran file diff --git a/vignettes/articles/create-augPred.Rmd b/vignettes/articles/create-augPred.Rmd new file mode 100644 index 0000000..8516541 --- /dev/null +++ b/vignettes/articles/create-augPred.Rmd @@ -0,0 +1,55 @@ +--- +title: "Created Augmented pred/ipred plots with `augPred()`" +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +This is a simple process to create individual predictions augmented +with more observations than was modeled. This allows smoother plots +and a better examination of the observed concentrations for an +individual and population. + +# Step 1: Convert the `Monolix` model to `rxode2`: + +```{r setup} + +library(monolix2rx) + +# First we need the location of the monolix mlxtran file. Since we are +# running an example, we will use one of the built-in examples in +# `monolix2rx` +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") +# You can use a control stream or other file. With the development +# version of `babelmixr2`, you can simply point to the listing file + +mod <- monolix2rx(pkgTheo) + +``` + + +# Step 2: convert the `rxode2` model to `nlmixr2` + +You can convert the model, `mod`, to a nlmixr2 fit object: + +```{r toNlmixr2} +library(babelmixr2) # provides as.nlmixr2 +fit <- as.nlmixr2(mod) + +fit +``` + +# Step 3: Create and plot an augmented prediction + +```{r augPred} +ap <- augPred(fit) + +head(ap) + +# This augpred looks odd: +plot(ap) +``` diff --git a/vignettes/articles/create-office.Rmd b/vignettes/articles/create-office.Rmd new file mode 100644 index 0000000..0051f9c --- /dev/null +++ b/vignettes/articles/create-office.Rmd @@ -0,0 +1,88 @@ +--- +title: "Create PowerPoint and Word documents using monolix2rx" +resource_files: + - mod-PowerPoint.pptx + - mod-Word.docx +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +# Step 1: import the model into `monolix2rx` + +```{r setup} + +library(monolix2rx) +library(babelmixr2) +library(nlmixr2rpt) +library(onbrand) + +library(nonmem2rx) + +# First we need the location of the monolix mlxtran file. Since we are +# running an example, we will use one of the built-in examples in +# `monolix2rx` +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") +# You can use a control stream or other file. With the development +# version of `babelmixr2`, you can simply point to the listing file + +mod <- monolix2rx(pkgTheo) + +``` + + + +# Step 2: convert the `rxode2` model to `nlmixr2` + +You can convert the model, `mod`, to a nlmixr2 fit object: + +```{r toNlmixr2} +fit <- as.nlmixr2(mod) + +fit +``` + +# Step 3: Create a PowerPoint file + +A PowerPoint can be created from your own [custom powerpoint +templates](https://nlmixr2.github.io/nlmixr2rpt/articles/Reporting_nlmixr_Fit_Results.html#customizing-reports-for-your-organization), +but in this example we will use the ones that come from `nlmixr2rpt` +directly: + +```{r toPptx} +obnd_pptx = read_template( + template = system.file(package="nlmixr2rpt", "templates","nlmixr_obnd_template.pptx"), + mapping = system.file(package="nlmixr2rpt", "templates","nlmixr_obnd_template.yaml")) + +obnd_pptx = report_fit( + fit = fit, + obnd = obnd_pptx) + +save_report(obnd_pptx, "mod-PowerPoint.pptx") +``` + +Which gives the powerpoint [here](mod-PowerPoint.pptx) + + +# Step 4: Create a Word file + +Just like in PowerPoint, you can customizeown [custom word templates](https://nlmixr2.github.io/nlmixr2rpt/articles/Reporting_nlmixr_Fit_Results.html#customizing-reports-for-your-organization), but in this example we will use the ones that come from `nlmixr2rpt` directly: + + +```{r} +obnd_docx = read_template( + template = system.file(package="nlmixr2rpt", "templates","nlmixr_obnd_template.docx"), + mapping = system.file(package="nlmixr2rpt", "templates","nlmixr_obnd_template.yaml")) + +obnd_docx = report_fit( + fit = fit, + obnd = obnd_docx) + +save_report(obnd_docx, "mod-Word.docx") +``` + +Which gives the word document [here](mod-Word.docx) diff --git a/vignettes/articles/create-vpc.Rmd b/vignettes/articles/create-vpc.Rmd new file mode 100644 index 0000000..e727372 --- /dev/null +++ b/vignettes/articles/create-vpc.Rmd @@ -0,0 +1,71 @@ +--- +title: "Easily Create a VPC using monolix2rx" +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` +This shows an easy work-flow to create a VPC using a Monolix model: + +# Step 1: Convert the `Monolix` model to `rxode2`: + +```{r setup} +library(babelmixr2) +library(monolix2rx) + +# First we need the location of the monolix mlxtran file. Since we are +# running an example, we will use one of the built-in examples in +# `monolix2rx` +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") +# You can use a control stream or other file. With the development +# version of `babelmixr2`, you can simply point to the listing file + +mod <- monolix2rx(pkgTheo) + +``` + + +# Step 2: convert the `rxode2` model to `nlmixr2` + +You can convert the model, `mod`, to a nlmixr2 fit object: + +```{r toNlmixr2} +fit <- as.nlmixr2(mod) + +fit +``` + +# Step 3: Perform the VPC + +From here we simply use `vpcPlot()` in conjunction with the `vpc` +package to get the regular and prediction-corrected VPCs and arrange +them on a single plot: + +```{r vpc} + +library(ggplot2) +p1 <- vpcPlot(fit, show=list(obs_dv=TRUE)) + +p1 <- p1 + ylab("Concentrations") + + rxode2::rxTheme() + + xlab("Time (hr)") + + xgxr::xgx_scale_x_time_units("hour", "hour") + +p1a <- p1 + xgxr::xgx_scale_y_log10() + +## A prediction-corrected VPC +p2 <- vpcPlot(fit, pred_corr = TRUE, show=list(obs_dv=TRUE)) +p2 <- p2 + ylab("Prediction-Corrected Concentrations") + + rxode2::rxTheme() + + xlab("Time (hr)") + + xgxr::xgx_scale_x_time_units("hour", "hour") + +p2a <- p2 + xgxr::xgx_scale_y_log10() + + +library(patchwork) +(p1 * p1a) / (p2 * p2a) +``` diff --git a/vignettes/articles/mod-PowerPoint.pptx b/vignettes/articles/mod-PowerPoint.pptx new file mode 100644 index 0000000..b954aba Binary files /dev/null and b/vignettes/articles/mod-PowerPoint.pptx differ diff --git a/vignettes/articles/mod-Word.docx b/vignettes/articles/mod-Word.docx new file mode 100644 index 0000000..d18e18a Binary files /dev/null and b/vignettes/articles/mod-Word.docx differ diff --git a/vignettes/articles/rxode2-validate.Rmd b/vignettes/articles/rxode2-validate.Rmd new file mode 100644 index 0000000..a166acc --- /dev/null +++ b/vignettes/articles/rxode2-validate.Rmd @@ -0,0 +1,141 @@ +--- +title: "Qualify rxode2 model against Monolix" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Qualify rxode2 model against Monolix} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +library(rxode2) +setRxThreads(1L) +library(data.table) +setDTthreads(1L) +``` + + +```{r setup} + +library(monolix2rx) +# You use the path to the monolix mlxtran file + +# In this case we will us the theophylline project included in monolix2rx +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") + +# Note you have to setup monolix2rx to use the model library or save +# the model as a separate file +mod <- monolix2rx(pkgTheo) + +print(mod) + +``` + +### Comparing differences between `Monolix` and `rxode2` + +You may wish to see where the differences in predictions are between +Monolix and rxode2. + +The `rxode2` generated outputs are compared with the `Monolix` +generated outputs for the following items: + +- **Population Predictions:** this shows if the model translation is + adequate to simulate general trends; This will validate structural + model's population parameters coupled with the model structure. + +- **Individual Predictions:** this shows if the model translation is + able to replicate the same values over all the subjects within the + modeling data-set. This validates the model can reproduce the + between subject variability observed in the study. + +- **Individual Weighted Residuals:** this is one step further than the + individual parameter validation, it couples the individual + predictions, the observations and the residual specification to + generate the individual weighted residuals. This is included to be + consistent with the `nonmem2rx` residuals. However, since this is + not needed to manually adjust the residual errors, this simply looks + at if the errors were converted correctly. + +**Note:** the only part that is not validated with these three metrics +is the between subject covariance matrix, `omega`. We assume this is +correct as long as it is read in correctly. + +## Comparing numerically + +If you want numerical differences, you can also get these from the +modified returned `ui` object. For the rtol, atol as follows you have: + +```{r tol} +mod$iwresAtol +mod$iwresRtol +mod$ipredAtol +mod$ipredRtol +mod$predAtol +mod$predAtol +``` + +You can see they do not exactly match but are very close (I would say +they validate). However you can explore these difference further if you wish +by looking at the `ipredCompare` and `predCompare` datasets: + +```{r compare} +head(mod$iwresCompare) + +head(mod$ipredCompare) + +head(mod$predCompare) +``` + +In these cases you can see that Monolix seems to round the values to 5 +digits, while `rxode2` keeps everything since it is solved in R +directly. + +Note this is the **observation data only** that is compared. Dosing +predictions are excluded from these comparisons. + +You can also explore the Monolix translated input dataset that was +used to make the validation predictions (dosing and observations) by +the `$monolixData` item: + +```{r monolixData} +head(mod$monolixData) # with nlme loaded you can also use getData(mod) +``` + +## Comparing visually + +The easiest way to visually compare the differences is by the plot method: + +```{r plot} + +plot(mod) # for general plot + +# you can also see individual comparisons +plot(mod, log="y", ncol=2, nrow=2, + xlab="Time (hr)", ylab="Concentrations", + page=1) + +# If you want all pages you could use: +# +plot(mod, log="y", ncol=2, nrow=2, + xlab="Time (hr)", ylab="Concentrations", + page=TRUE) +``` + + +## Notes on validation + +The validation of the model uses the best data available for Monolix +estimates. This is: + +- `theta` or population parameters +- `eta` or individual parameters + +The `omega` and `sigma` matrices are captured. When the nlmixr2 model +is fully qualified, the `IWRES` validation ensures the residual errors +are specified correctly. Otherwise `omega` and `sigma` values do not contribute to +the validation. Also the overall covariance is captured, but not used +in the validation. diff --git a/vignettes/articles/simulate-extra-items.Rmd b/vignettes/articles/simulate-extra-items.Rmd new file mode 100644 index 0000000..126bfef --- /dev/null +++ b/vignettes/articles/simulate-extra-items.Rmd @@ -0,0 +1,124 @@ +--- +title: "Simulate Derived Variables from imported Monolix model" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Simulate Derived Variables from imported Monolix model} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +library(rxode2) +setRxThreads(1L) +library(data.table) +setDTthreads(1L) +``` + +This page shows a simple work-flow for directly simulating a different +dosing paradigm with new derived items, in this case `AUC`. + + +## Step 1: Import the model + +```{r setup} +library(monolix2rx) +library(rxode2) + + +# First we need the location of the nonmem control stream Since we are running an example, we will use one of the built-in examples in `nonmem2rx` +ctlFile <- system.file("mods/cpt/runODE032.ctl", package="nonmem2rx") +# You can use a control stream or other file. With the development +# version of `babelmixr2`, you can simply point to the listing file + +# You use the path to the monolix mlxtran file + +# In this case we will us the theophylline project included in monolix2rx +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") + +# Note you have to setup monolix2rx to use the model library or save +# the model as a separate file +mod <- monolix2rx(pkgTheo) + +print(mod) + +``` + +## Step 2: Add AUC calculation + +The concentration in this case is the `Cc` from the model, a trick to +get the `AUC` is to have an additional ODE `d/dt(AUC) <- Cc` and use +some reset to get it per dosing period. + +However, this additional parameter is not part of the original model. +The calculation of AUC would depend on the number of observations in +your model, and for sparse data wouldn't be terribly accurate. + +One thing you can do is to use model piping append `d/dt(AUC) <- Cc` to +the imported model: + +```{r modAuc} +modAuc <- mod %>% + model(d/dt(AUC) <- Cc, append=TRUE) + +modAuc +``` + +You can also use `append=NA` to pre-pend or `append=f` to put the ODE +right after the `f` line in the model. + +## Step 3: Setup event table to calculate the AUC for a different dosing paradigm: + +Lets say that in this case instead of a single dose, we want to see +what the concentration profile is with a single day of BID dosing. In +this case is done by creating a [quick event +table](https://nlmixr2.github.io/rxode2/articles/rxode2-event-table.html). + +In this case since we are also wanting `AUC` per dosing period, you +can add a reset dose to the `AUC` compartment every time a dose is given +(so it will only track the AUC of the current dose): + +```{r eventTable} +ev <- et(amt=4, ii=12, until=24) %>% + et(amt=0, ii=12, until=24, cmt="AUC", evid=5) %>% # replace AUC with zero at dosing + et(c(0, 4, 8, 11.999, 12, 12.01, 14, 20, 23.999, 24, 24.001, 28, 32, 36)) %>% + et(id=1:10) +``` + +## Step 4: Solve using `rxode2` + +In this step, we solve the model with the new event table for the 10 +subjects: + +```{r solve} +s <- rxSolve(modAuc, ev) +``` + +Note that since this derived from a `nonmem2rx` model, the default +solving will match the tolerances and methods specified in your +`NONMEM` model. + +## Step 5: Exploring the simulation (by plotting), and summarizing (dplyr) + +This solved object acts the same as any other `rxode2` solved object, +so you can use the `plot()` function to see the individual running AUC profiles +you simulated: + +```{r plot} +library(ggplot2) +plot(s, AUC) + + ylab("Running AUC") +``` + +You can also select the points near the dosing to get the AUC for the +interval: + +```{r gatherAuc} +library(dplyr) +s %>% filter(time %in% c(11.999, 23.999)) %>% + mutate(time=round(time)) %>% + select(id, time, AUC) +``` diff --git a/vignettes/articles/simulate-new-dosing.Rmd b/vignettes/articles/simulate-new-dosing.Rmd new file mode 100644 index 0000000..3d57664 --- /dev/null +++ b/vignettes/articles/simulate-new-dosing.Rmd @@ -0,0 +1,85 @@ +--- +title: "Simulate New dosing from Monolix model" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Simulate New dosing from Monolix model} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +library(rxode2) +setRxThreads(1L) +library(data.table) +setDTthreads(1L) +``` + +This page shows a simple work-flow for directly simulating a different +dosing paradigm than what was modeled. + + +## Step 1: Import the model + +```{r setup} +library(monolix2rx) +library(rxode2) + +# You use the path to the monolix mlxtran file + +# In this case we will us the theophylline project included in monolix2rx +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") + +# Note you have to setup monolix2rx to use the model library or save +# the model as a separate file +mod <- monolix2rx(pkgTheo) + +print(mod) + +``` + +## Step 2: Look at a different dosing paradigm + +Lets say that in this case instead of a single dose, we want to see +what the concentration profile is with a single day of BID dosing. +In this case is done by creating a [quick event table](https://nlmixr2.github.io/rxode2/articles/rxode2-event-table.html): + +```{r eventTable} +ev <- et(amt=4, ii=12, until=24) %>% + et(list(c(0, 2), # add observations in windows + c(4, 6), + c(8, 12), + c(14, 18), + c(20, 26), + c(28, 32), + c(32, 36), + c(36, 44))) %>% + et(id=1:10) +``` + +## Step 3: solve using `rxode2` + +In this step, we solve the model with the new event table for the 10 +subjects: + +```{r solve} +s <- rxSolve(mod, ev) +``` + +Note that since this is a `nonmem2rx` model, the default solving will +match the tolerances and methods specified in your `NONMEM` model. + +## Step 4: exploring the simulation (by plotting) + +This solved object acts the same as any other `rxode2` solved object, +so you can use the `plot()` function to see the individual profiles +you simulated: + +```{r plot} +library(ggplot2) +plot(s, ipredSim) + + ylab("Concentrations") +``` diff --git a/vignettes/articles/simulate-uncertainty.Rmd b/vignettes/articles/simulate-uncertainty.Rmd new file mode 100644 index 0000000..50e8361 --- /dev/null +++ b/vignettes/articles/simulate-uncertainty.Rmd @@ -0,0 +1,98 @@ +--- +title: "Simulate using Parameter Uncertainty" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Simulate using Parameter Uncertainty} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +library(rxode2) +setRxThreads(1L) +library(data.table) +setDTthreads(1L) +``` + +This page shows a simple work-flow for directly simulating a different +dosing paradigm than what was modeled taking into account the modeled +uncertainty. This workflow is very similar to simply [simulating +without uncertainty](simulate-new-dosing.html) in the parameters +themselves. + +## Step 1: Import the model + +```{r setup} + +library(monolix2rx) +library(rxode2) +# its best practice to set the seed for the simulations +set.seed(42) +rxSetSeed(42) + + +# You use the path to the monolix mlxtran file + +# In this case we will us the theophylline project included in monolix2rx +pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") + +# Note you have to setup monolix2rx to use the model library or save +# the model as a separate file +mod <- monolix2rx(pkgTheo) + +print(mod) +``` +## Step 2: Look at a different dosing paradigm + +Lets say that in this case instead of a single dose, we want to see +what the concentration profile is with a single day of BID dosing. In +this case is done by creating a [quick event +table](https://nlmixr2.github.io/rxode2/articles/rxode2-event-table.html). + +```{r eventTable} +ev <- et(amt=4, ii=12, until=24) %>% + et(c(1:6, seq(8, 24, by=2))) %>% + et(id=1:100) +``` + + + +## Step 3: Solve using the uncertainty in the NONMEM model + +To use the uncertainty in the model, it is a simple matter of telling +how many times `rxode2()` should sample with `nStud=X`. In this case +we will use `100`. + +```{r rxSolve} +s <- rxSolve(mod, ev, nStud=100) + +s +``` + + +## Step 4: Summarize and plot + +Since there is a bunch of data, a confidence band of the simulation with uncertainty would be helpful. + +One way to do that is to select the interesting components, create a confidence interval and then plot the confidence bands: + + + +```{r confint} +sci <- confint(s, parm=c("CONC", "sim")) + +sci + +p1 <- plot(sci) + +p2 <- plot(sci, log="y") + +library(patchwork) + +p1/p2 + +```