diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 5cc76ad2..aed46307 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -66,6 +66,7 @@ jobs: nlmixr2/nlmixr2plot nlmixr2/nlmixr2 nlmixr2/nonmem2rx + nlmixr2/monolix2rx lixoftConnectors=?ignore needs: check diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 9afbfe4d..6e55bf51 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -42,6 +42,7 @@ jobs: nlmixr2/rxode2ll nlmixr2/rxode2 nlmixr2/nonmem2rx + nlmixr2/monolix2rx nlmixr2/nlmixr2est nlmixr2/nlmixr2rpt mrgsolve diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index ae396791..a1a12083 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -40,6 +40,7 @@ jobs: nlmixr2/nlmixr2plot nlmixr2/nlmixr2 nlmixr2/nonmem2rx + nlmixr2/monolix2rx lixoftConnectors=?ignore needs: coverage diff --git a/DESCRIPTION b/DESCRIPTION index cbcbae27..0c32ab25 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -39,6 +39,7 @@ Imports: lotri, nlmixr2est (>= 2.1.6), nonmem2rx (>= 0.1.3), + monolix2rx, methods, qs, rex, diff --git a/NAMESPACE b/NAMESPACE index 47ea46b6..034190c0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand S3method(as.nlmixr2,default) +S3method(as.nlmixr2,monolix2rx) S3method(as.nlmixr2,nonmem2rx) S3method(getValidNlmixrCtl,monolix) S3method(getValidNlmixrCtl,nonmem) @@ -19,6 +20,7 @@ S3method(nmGetDistributionNonmemLines,norm) S3method(nmGetDistributionNonmemLines,rxUi) S3method(nmGetDistributionNonmemLines,t) S3method(nmObjGetControl,monolix) +S3method(nmObjGetControl,monolix2rx) S3method(nmObjGetControl,nonmem) S3method(nmObjGetControl,nonmem2rx) S3method(nmObjGetFoceiControl,monolix) @@ -151,7 +153,9 @@ export(bblDatToPknca) export(bblDatToRxode) export(getStandardColNames) export(getValidNlmixrCtl) +export(mlxtran) export(modelUnitConversion) +export(monolix2rx) export(monolixControl) export(nlmixr2Est) export(nmGetDistributionMonolixLines) @@ -159,6 +163,11 @@ export(nmGetDistributionNonmemLines) export(nmObjGetControl) export(nmObjGetFoceiControl) export(nmObjHandleControlObject) +export(nmcov) +export(nmext) +export(nminfo) +export(nmtab) +export(nmxml) export(nonmem2rx) export(nonmemControl) export(pkncaControl) @@ -169,6 +178,8 @@ export(rxToNonmem) export(rxUiGet) export(simplifyUnit) importFrom(methods,is) +importFrom(monolix2rx,mlxtran) +importFrom(monolix2rx,monolix2rx) importFrom(nlmixr2,nlmixr2) importFrom(nlmixr2est,getValidNlmixrCtl) importFrom(nlmixr2est,nlmixr2Est) @@ -176,6 +187,11 @@ importFrom(nlmixr2est,nmObjGetControl) importFrom(nlmixr2est,nmObjGetFoceiControl) importFrom(nlmixr2est,nmObjHandleControlObject) importFrom(nonmem2rx,as.nonmem2rx) +importFrom(nonmem2rx,nmcov) +importFrom(nonmem2rx,nmext) +importFrom(nonmem2rx,nminfo) +importFrom(nonmem2rx,nmtab) +importFrom(nonmem2rx,nmxml) importFrom(nonmem2rx,nonmem2rx) importFrom(rxode2,.minfo) importFrom(rxode2,`model<-`) diff --git a/R/as.nlmixr2.R b/R/as.nlmixr2.R index 9970d786..2e58e078 100644 --- a/R/as.nlmixr2.R +++ b/R/as.nlmixr2.R @@ -6,6 +6,8 @@ #' @param rxControl is the `rxode2::rxControl()` options, which is #' generally needed for how `addl` doses are handled in the #' translation +#' @param ci is the confidence interval of the residual differences +#' calculated (by default 0.95) #' @return nlmixr2 fit object #' @export #' @author Matthew L. Fidler @@ -63,7 +65,7 @@ #' print(fit) #' #' } -as.nlmixr2 <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl()) { +as.nlmixr2 <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl(), ci=0.95) { UseMethod("as.nlmixr2") } #' @rdname as.nlmixr2 @@ -71,7 +73,7 @@ as.nlmixr2 <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode as.nlmixr <- as.nlmixr2 #' @export -as.nlmixr2.default <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl()) { +as.nlmixr2.default <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl(), ci=0.95) { stop("cannot figure out how to create an nlmixr2 object from the input", call.=FALSE) } diff --git a/R/as.nlmixr2monolixr2rx.R b/R/as.nlmixr2monolixr2rx.R new file mode 100644 index 00000000..cf5d94a0 --- /dev/null +++ b/R/as.nlmixr2monolixr2rx.R @@ -0,0 +1,139 @@ +#' @export +nmObjGetControl.monolix2rx <- function(x, ...) { + .env <- x[[1]] + if (exists("control", .env)) { + .control <- get("control", .env) + if (inherits(.control, "foceiControl")) return(.control) + } + if (exists("foceiControl0", .env)) { + .control <- get("foceiControl0", .env) + if (inherits(.control, "foceiControl")) return(.control) + } + stop("cannot find monolix2rx related control object", call.=FALSE) +} + +.monolix2rxToFoceiControl <- function(env, model, assign=FALSE) { + ## maxSS=nbSSDoses + 1, + ## minSS=nbSSDoses, + ## ssAtol=100, + ## ssRtol=100, + ## atol=ifelse(stiff, 1e-9, 1e-6), + ## rtol=ifelse(stiff, 1e-6, 1e-3), + ## method=ifelse(stiff, "liblsoda", "dop853") + .nbSsDoses <- monolix2rx::.getNbdoses(model) + .stiff <- monolix2rx::.getStiff(model) + .rxControl <- rxode2::rxControl(covsInterpolation="locf", + atol=ifelse(.stiff, 1e-9, 1e-6), + rtol=ifelse(.stiff, 1e-6, 1e-3), + ssRtol=100, + ssAtol=100, + maxSS=.nbSsDoses + 1, + minSS=.nbSsDoses, + method=ifelse(.stiff, "liblsoda", "dop853"), + safeZero=FALSE) + .foceiControl <- nlmixr2est::foceiControl(rxControl=.rxControl, + maxOuterIterations = 0L, maxInnerIterations = 0L, + etaMat = env$etaMat, + covMethod=0L, + interaction = 1L) + if (assign) + env$control <- .foceiControl + .foceiControl +} + +#' @export +as.nlmixr2.monolix2rx <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl(), ci=0.95) { + #need x$nonmemData + # need x to have at least one endpoint + # The environment needs: + env <- new.env(parent=emptyenv()) + x <- rxode2::rxUiDecompress(x) + nlmixr2est::nlmixrWithTiming("as.nlmixr2", { + .ui <- new.env(parent=emptyenv()) + .oldUi <- x + for (n in ls(envir=.oldUi, all.names=TRUE)) { + assign(n, get(n, envir=.oldUi), envir=.ui) + } + class(.ui) <- class(.oldUi) + # - $table for table options -- already present + env$table <- table + env$origData <- x$monolixData + nlmixr2est::.foceiPreProcessData(env$origData, env, .ui, rxControl) + # - $origData -- Original Data -- already present + # - $dataSav -- Processed data from .foceiPreProcessData --already present + # - $idLvl -- Level information for ID factor added -- already present + env$ui <- .ui + # - $ui for ui fullTheta Full theta information + env$fullTheta <- .ui$monolixFullTheta + # - $etaObf data frame with ID, etas and OBJI + env$etaObf <- .ui$monolixEtaObf + if (is.null(env$etaObf)) { + .df <- data.frame(ID=unique(env$dataSav$ID)) + for (.n in .getEtaNames(.ui)) { + .df[[.n]] <- 0 + } + .df[["OBJI"]] <- NA_real_ + env$etaObf <- .df + warning("since Monolix did not output between subject variability, assuming all ETA(#) are zero", + call.=FALSE) + } + # - $cov For covariance + .cov <- .ui$monolixCovariance + if (!is.null(.cov)) { + env$cov <- .cov + # - $covMethod for the method of calculating the covariance + env$covMethod <- "monolix2rx" + } + # - $objective objective function value + env$objective <- .ui$monolixObjf + # - $extra Extra print information + env$extra <- paste0(" reading Monolix ver ", env$ui$monolixOutputVersion) + # - $method Estimation method (for printing) + env$method <- "monolix2rx" + # - $omega Omega matrix + env$omega <- .ui$monolixOmega + # - $theta Is a theta data frame + env$theta <- .ui$monolixTheta + # - $model a list of model information for table generation. Needs a `predOnly` model + env$model <- .ui$ebe + # - $message Message for display + env$message <- "" + # - $est estimation method + env$est <- "monolix2rx" + # - $ofvType (optional) tells the type of ofv is currently being used + #env$ofvType + env$ofvType <- .ui$monolixObjfType + # Add parameter history + env$nobs <- x$dfObs + env$nobs2<- x$dfObs + # Run before converting to nonmemControl + .objf <- .ui$monolixObjf + # When running the focei problem to create the nlmixr object, you also need a + # foceiControl object + .monolix2rxToFoceiControl(env, x, TRUE) + .ret <- nlmixr2est::nlmixr2CreateOutputFromUi(env$ui, data=env$origData, + control=env$control, table=env$table, + env=env, est="monolix2rx") + if (inherits(.ret, "nlmixr2FitData")) { + assign("monolixControl", list(ci=ci), .ret$env) + .msg <- .monolixMergePredsAndCalcRelativeErr(.ret) + rm("monolixControl", envir=.ret$env) + .msg$message <- c(.msg$message) + .tmp <- .ret$ui$monolixParHistory + assign("message", paste(.msg$message, collapse="\n "), envir=.ret$env) + if (is.null(.tmp)) { + .minfo("monolix parameter history needs exported charts, please export charts") + } else { + .tmp$type <- "Unscaled" + assign("parHistData", .tmp, .ret$env) + .minfo("monolix parameter history integrated into fit object") + } + } + ## .time <- get("time", .ret$env) + ## .time <- .time[,!(names(.time) %in% c("optimize", "covariance"))] + ## assign("time", + ## cbind(.time, data.frame(NONMEM=.ui$nonmemRunTime)), + ## .ret$env) + .ret + }, env=env) +} diff --git a/R/as.nlmixr2nonmem2rx.R b/R/as.nlmixr2nonmem2rx.R index 3b6fe99e..37dc428d 100644 --- a/R/as.nlmixr2nonmem2rx.R +++ b/R/as.nlmixr2nonmem2rx.R @@ -27,11 +27,11 @@ nmObjGetControl.nonmem2rx <- function(x, ...) { interaction = 1L) if (assign) env$control <- .foceiControl - .foceiControl + .foceiControl } #' @export -as.nlmixr2.nonmem2rx <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl()) { +as.nlmixr2.nonmem2rx <- function(x, ..., table=nlmixr2est::tableControl(), rxControl=rxode2::rxControl(), ci=0.95) { #need x$nonmemData # need x to have at least one endpoint # The environment needs: @@ -105,7 +105,9 @@ as.nlmixr2.nonmem2rx <- function(x, ..., table=nlmixr2est::tableControl(), rxCon control=env$control, table=env$table, env=env, est="nonmem2rx") if (inherits(.ret, "nlmixr2FitData")) { + assign("nonmemControl", list(ci=ci), .ret$env) .msg <- .nonmemMergePredsAndCalcRelativeErr(.ret) + rm("nonmemControl", envir=.ret$env) .prderrPath <- file.path(x$nonmemExportPath, "PRDERR") .msg$message <- c(.ui$nonmemTransMessage, .ui$nonmemTermMessage, diff --git a/R/monolixNlmixr2est.R b/R/monolixNlmixr2est.R index 83a0fe12..062d0de0 100644 --- a/R/monolixNlmixr2est.R +++ b/R/monolixNlmixr2est.R @@ -235,7 +235,7 @@ .runLock <- .ui$monolixRunLock .cmd <- rxode2::rxGetControl(.ui, "runCommand", "") - if (file.exists(.qs)) { +if (checkmate::testFileExists(.qs)) { .minfo("load saved nlmixr2 object") .ret <- qs::qread(.qs) if (!exists("parHistData", .ret$env)) { @@ -250,7 +250,7 @@ } } return(.ret) - } else if (!file.exists(.model)) { + } else if (!checkmate::testFileExists(.model)) { .minfo("writing monolix files") writeLines(text=.modelText, con=.model) writeLines(text=.mlxtranText, con=.mlxtran) diff --git a/R/monolixReadData.R b/R/monolixReadData.R index 0999c731..d29f0ac3 100644 --- a/R/monolixReadData.R +++ b/R/monolixReadData.R @@ -444,30 +444,58 @@ rxUiGet.monolixPreds <- function(x, ...) { .predDf <- .ui$predDf .exportPath <- rxUiGet.monolixExportPath(x, ...) if (!file.exists(.exportPath)) return(NULL) + .mlxtran <- monolix2rx::.monolixGetMlxtran(.ui) + if (inherits(.mlxtran, "monolix2rxMlxtran")) { + if (length(.predDf$var) > 1) { + do.call("rbind", lapply(seq_along(.predDf$cond), + function(i) { + .var <- .predDf$cond[i] + .file <- file.path(.exportPath, + paste0("predictions_", .var, ".txt")) + .monolixWaitForFile(.file) + .ret <- read.csv(.file) + .ret$CMT <- .predDf$cond[i] + names(.ret) <- sub("id", "ID", + sub("time", "TIME", + sub(.var, "DV", names(.ret)))) + .ret + })) + } else { + .var <- .predDf$cond + .file <- file.path(.exportPath,"predictions.txt") + .monolixWaitForFile(.file) + .ret <- read.csv(.file) + names(.ret) <- sub("id", "ID", + sub("time", "TIME", + sub(.var, "DV", names(.ret)))) + .ret - if (length(.predDf$var) > 1) { - do.call("rbind", lapply(seq_along(.predDf$var), - function(i){ - .var <- .predDf$var[i] - .file <- file.path(.exportPath, - paste0("predictions_rx_prd_", .var, ".txt")) - .monolixWaitForFile(.file) - .ret <- read.csv(.file) - .ret$CMT <- .predDf$cond[i] - names(.ret) <- sub("id", "ID", - sub("time", "TIME", - sub(paste0("rx_prd_", .var), "DV", names(.ret)))) - .ret - })) + } } else { - .var <- .predDf$var - .file <- file.path(.exportPath,"predictions.txt") - .monolixWaitForFile(.file) - .ret <- read.csv(.file) - names(.ret) <- sub("id", "ID", - sub("time", "TIME", - sub(paste0("rx_prd_", .var), "DV", names(.ret)))) - .ret + if (length(.predDf$var) > 1) { + do.call("rbind", lapply(seq_along(.predDf$var), + function(i) { + .var <- .predDf$var[i] + .file <- file.path(.exportPath, + paste0("predictions_rx_prd_", .var, ".txt")) + .monolixWaitForFile(.file) + .ret <- read.csv(.file) + .ret$CMT <- .predDf$cond[i] + names(.ret) <- sub("id", "ID", + sub("time", "TIME", + sub(paste0("rx_prd_", .var), "DV", names(.ret)))) + .ret + })) + } else { + .var <- .predDf$var + .file <- file.path(.exportPath,"predictions.txt") + .monolixWaitForFile(.file) + .ret <- read.csv(.file) + names(.ret) <- sub("id", "ID", + sub("time", "TIME", + sub(paste0("rx_prd_", .var), "DV", names(.ret)))) + .ret + } } } diff --git a/R/monolixRxUiGet.R b/R/monolixRxUiGet.R index e0ddeabd..c8313e92 100644 --- a/R/monolixRxUiGet.R +++ b/R/monolixRxUiGet.R @@ -15,6 +15,16 @@ rxUiGet.monolixModelName <- function(x, ...) { #' @export rxUiGet.monolixExportPath <- function(x, ...) { .ui <- x[[1]] + # Handle monolix2rx as well + .mlxtran <- monolix2rx::.monolixGetMlxtran(.ui) + if (inherits(.mlxtran, "monolix2rxMlxtran")) { + .wd <- attr(.mlxtran, "dirn") + if (!checkmate::testDirectoryExists(.wd)) .wd <- getwd() + withr::with_dir(.wd, { + .exportPath <- .mlxtran$MONOLIX$SETTINGS$GLOBAL$exportpath + return(path.expand(file.path(.wd, .exportPath))) + }) + } .extra <- "" .num <- rxode2::rxGetControl(.ui, ".modelNumber", 0) if (.num > 0) { diff --git a/R/nonmemReadData.R b/R/nonmemReadData.R index 03717fbb..81a5dfae 100644 --- a/R/nonmemReadData.R +++ b/R/nonmemReadData.R @@ -291,7 +291,7 @@ rxUiGet.nonmemPreds <- function(x, ...) { .ret <- .ret[.ret$NMREP ==1, names(.ret) != "NMREP"] setNames(.ret, c("ID", "TIME", "nonmemIPRED", "nonmemPRED", "RXROW")) - + } } @@ -333,11 +333,7 @@ rxUiGet.nonmemRoundingErrors <- function(x, ...) { .tmp$RXROW <- fit$env$.rownum .by <- c("ID", "TIME", "RXROW") .ret <- merge(.np, .tmp, by=.by) -- if (!is.numeric(fit$nonmemControl$ci)) { - .ci0 <- 0.95 - } else { - .ci0 <- fit$nonmemControl$ci - } + .ci0 <- fit$nonmemControl$ci .ci <- (1 - .ci0) / 2 .q <- c(0, .ci, 0.5, 1 - .ci, 1) .qi <- stats::quantile(with(.ret, 100*abs((IPRED-nonmemIPRED)/nonmemIPRED)), .q, na.rm=TRUE) diff --git a/R/reexport.R b/R/reexport.R index 0cd1b494..d7c260ec 100644 --- a/R/reexport.R +++ b/R/reexport.R @@ -34,7 +34,34 @@ nlmixr2est::nmObjGetControl #' @export nonmem2rx::nonmem2rx +#' @importFrom nonmem2rx nmcov +#' @export +nonmem2rx::nmcov + +#' @importFrom nonmem2rx nmext +#' @export +nonmem2rx::nmext + +#' @importFrom nonmem2rx nminfo +#' @export +nonmem2rx::nminfo + +#' @importFrom nonmem2rx nmtab +#' @export +nonmem2rx::nmtab + +#' @importFrom nonmem2rx nmxml +#' @export +nonmem2rx::nmxml + #' @importFrom nonmem2rx as.nonmem2rx #' @export nonmem2rx::as.nonmem2rx +#' @importFrom monolix2rx monolix2rx +#' @export +monolix2rx::monolix2rx + +#' @importFrom monolix2rx mlxtran +#' @export +monolix2rx::mlxtran diff --git a/README.Rmd b/README.Rmd index 6bfe4004..73a02bf6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -16,7 +16,7 @@ knitr::opts_chunk$set( # babelmixr2 -[![R-CMD-check](https://github.com/nlmixr2/babelmixr2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/nlmixr2/babelmixr2/actions/workflows/R-CMD-check.yaml) +[![R-CMD-check](https://github.com/nlmixr2/babelmixr2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/nlmixr2/babelmixr2/actions/workflows/R-CMD-check.yaml) [![CRAN version](http://www.r-pkg.org/badges/version/babelmixr2)](https://cran.r-project.org/package=babelmixr2) [![CRAN total downloads](https://cranlogs.r-pkg.org/badges/grand-total/babelmixr2)](https://cran.r-project.org/package=babelmixr2) [![CRAN total downloads](https://cranlogs.r-pkg.org/badges/babelmixr2)](https://cran.r-project.org/package=babelmixr2) @@ -55,14 +55,19 @@ Babelmixr2 can help you by: - Running your nlmixr2 model in a commercial nonlinear mixed effects modeling tool like [`NONMEM`](https://nlmixr2.github.io/babelmixr2/articles/running-nonmem.html) or `Monolix` - + - Convert your [`NONMEM` model to a nlmixr2 model](https://nlmixr2.github.io/nonmem2rx/articles/convert-nlmixr2.html) (in conjunction with `nonmem2rx`) - + + - Convert you [`Monolix` model to a nlmixr2 + model](https://nlmixr2.github.io/nonmem2rx/articles/convert-nlmixr2.html) + (in conjunction with `monolix2rx`) + - Calculate scaling factors and automatically add initial conditions based on non-compartmental analysis (using `PKNCA`) + - Perform Optimal design using nlmixr2 as an interface to `PopED` ## Monolix Setup @@ -72,9 +77,10 @@ While not required, you can get/install the R 'lixoftConnectors' package in the 'lixoftConnectors' is available, R can run 'Monolix' directly instead of using a command line. -## Example +## PKNCA Example -After installed, if you use the standard interface, you can obtain new initial estimates with PKNCA: +After installed, if you use the standard interface, you can obtain new +initial estimates with PKNCA: ```r mod <- @@ -84,13 +90,21 @@ mod <- ) ``` -or, you can convert to Monolix with +## Monolix example + +With babelmixr2 loaded, you can use `nlmixr2` to convert a nlmixr2 +model to Monolix, run with monolix, and import back to nlmixr2 with +the following: ```r mod <- nlmixr(nlmixrFun, nlmmixrData, est="monolix") ``` -or, you can convert to NONMEM with +## NONMEM example + +With babelmixr2 loadid you can use `nlmixr2` to convert a nlmixr2 +model to NONMEM, run NONMEM and import back to nlmixr2 with the +following: ```r mod <- nlmixr(nlmixrFun, nlmmixrData, est="nonmem") diff --git a/README.md b/README.md index 93e7e8c8..d0d6bbe1 100644 --- a/README.md +++ b/README.md @@ -46,17 +46,23 @@ Otherwise you can always install from GitHub: Babelmixr2 can help you by: -- Running your nlmixr2 model in a commercial nonlinear mixed effects - modeling tool like - [`NONMEM`](https://nlmixr2.github.io/babelmixr2/articles/running-nonmem.html) - or `Monolix` + - Running your nlmixr2 model in a commercial nonlinear mixed effects + modeling tool like + [`NONMEM`](https://nlmixr2.github.io/babelmixr2/articles/running-nonmem.html) + or `Monolix` -- Convert your [`NONMEM` model to a nlmixr2 - model](https://nlmixr2.github.io/nonmem2rx/articles/convert-nlmixr2.html) - (in conjunction with `nonmem2rx`) + - Convert your [`NONMEM` model to a nlmixr2 + model](https://nlmixr2.github.io/nonmem2rx/articles/convert-nlmixr2.html) + (in conjunction with `nonmem2rx`) -- Calculate scaling factors and automatically add initial conditions - based on non-compartmental analysis (using `PKNCA`) + - Convert you [`Monolix` model to a nlmixr2 + model](https://nlmixr2.github.io/nonmem2rx/articles/convert-nlmixr2.html) + (in conjunction with `monolix2rx`) + + - Calculate scaling factors and automatically add initial conditions + based on non-compartmental analysis (using `PKNCA`) + + - Perform Optimal design using nlmixr2 as an interface to `PopED` ## Monolix Setup @@ -66,7 +72,7 @@ in the ‘Monolix’ installation, as described at the following url When ‘lixoftConnectors’ is available, R can run ‘Monolix’ directly instead of using a command line. -## Example +## PKNCA Example After installed, if you use the standard interface, you can obtain new initial estimates with PKNCA: @@ -79,13 +85,20 @@ mod <- ) ``` -or, you can convert to Monolix with +## Monolix example + +With babelmixr2 loaded, you can use `nlmixr2` to convert a nlmixr2 model +to Monolix, run with monolix, and import back to nlmixr2 with the +following: ``` r mod <- nlmixr(nlmixrFun, nlmmixrData, est="monolix") ``` -or, you can convert to NONMEM with +## NONMEM example + +With babelmixr2 loadid you can use `nlmixr2` to convert a nlmixr2 model +to NONMEM, run NONMEM and import back to nlmixr2 with the following: ``` r mod <- nlmixr(nlmixrFun, nlmmixrData, est="nonmem") diff --git a/man/as.nlmixr2.Rd b/man/as.nlmixr2.Rd index cdcc3568..684cd2eb 100644 --- a/man/as.nlmixr2.Rd +++ b/man/as.nlmixr2.Rd @@ -9,14 +9,16 @@ as.nlmixr2( x, ..., table = nlmixr2est::tableControl(), - rxControl = rxode2::rxControl() + rxControl = rxode2::rxControl(), + ci = 0.95 ) as.nlmixr( x, ..., table = nlmixr2est::tableControl(), - rxControl = rxode2::rxControl() + rxControl = rxode2::rxControl(), + ci = 0.95 ) } \arguments{ @@ -29,6 +31,9 @@ as.nlmixr( \item{rxControl}{is the \code{rxode2::rxControl()} options, which is generally needed for how \code{addl} doses are handled in the translation} + +\item{ci}{is the confidence interval of the residual differences +calculated (by default 0.95)} } \value{ nlmixr2 fit object diff --git a/man/reexports.Rd b/man/reexports.Rd index 0dd8d3b9..7491f05f 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -12,7 +12,14 @@ \alias{nmObjHandleControlObject} \alias{nmObjGetControl} \alias{nonmem2rx} +\alias{nmcov} +\alias{nmext} +\alias{nminfo} +\alias{nmtab} +\alias{nmxml} \alias{as.nonmem2rx} +\alias{monolix2rx} +\alias{mlxtran} \title{Objects exported from other packages} \keyword{internal} \description{ @@ -20,9 +27,11 @@ These objects are imported from other packages. Follow the links below to see their documentation. \describe{ + \item{monolix2rx}{\code{\link[monolix2rx]{mlxtran}}, \code{\link[monolix2rx]{monolix2rx}}} + \item{nlmixr2est}{\code{\link[nlmixr2est:getValidNlmixrControl]{getValidNlmixrCtl}}, \code{\link[nlmixr2est]{nlmixr2Est}}, \code{\link[nlmixr2est]{nmObjGetControl}}, \code{\link[nlmixr2est]{nmObjGetFoceiControl}}, \code{\link[nlmixr2est]{nmObjHandleControlObject}}} - \item{nonmem2rx}{\code{\link[nonmem2rx]{as.nonmem2rx}}, \code{\link[nonmem2rx]{nonmem2rx}}} + \item{nonmem2rx}{\code{\link[nonmem2rx]{as.nonmem2rx}}, \code{\link[nonmem2rx]{nmcov}}, \code{\link[nonmem2rx]{nmext}}, \code{\link[nonmem2rx]{nminfo}}, \code{\link[nonmem2rx]{nmtab}}, \code{\link[nonmem2rx]{nmxml}}, \code{\link[nonmem2rx]{nonmem2rx}}} \item{rxode2}{\code{\link[rxode2:dot-minfo]{.minfo}}, \code{\link[rxode2]{rxModelVars}}, \code{\link[rxode2]{rxUiGet}}} }} diff --git a/tests/testthat/test-as-nlmixr2.R b/tests/testthat/test-as-nlmixr2.R index decb47d6..4966509f 100644 --- a/tests/testthat/test-as-nlmixr2.R +++ b/tests/testthat/test-as-nlmixr2.R @@ -6,7 +6,7 @@ test_that("nlmixr2 translation from nonmem2x", { skip_on_cran() - + mod <- .nonmem2rx(system.file("mods/cpt/runODE032.ctl", package="nonmem2rx"), determineError=FALSE, lst=".res", save=FALSE) @@ -60,3 +60,17 @@ test_that("nlmixr2 translation from nonmem2x", { }) +.monolix2rx <- function(...) suppressWarnings(suppressMessages(monolix2rx::monolix2rx(...))) + +test_that("nlmixr2 translation from monolix2rx", { + skip_on_cran() + + pkgTheo <- system.file("theo/theophylline_project.mlxtran", package="monolix2rx") + + mod <- .monolix2rx(pkgTheo) + + fit <- .as.nlmixr2(mod) + + expect_true(inherits(fit, "nlmixr2FitData")) + +})