Skip to contents

Step 1: import the model into nonmem2rx

library(nonmem2rx)
library(babelmixr2)
#> Loading required package: nlmixr2
#> Loading required package: nlmixr2data
library(nlmixr2rpt)
library(onbrand)

library(nonmem2rx)

# 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

mod <- nonmem2rx(ctlFile, lst=".res", save=FALSE)
#>  getting information from  '/home/runner/work/_temp/Library/nonmem2rx/mods/cpt/runODE032.ctl'
#>  reading in xml file
#>  done
#>  reading in phi file
#>  done
#>  reading in lst file
#>  abbreviated list parsing
#>  done
#>  done
#>  splitting control stream by records
#>  done
#>  Processing record $INPUT
#>  Processing record $MODEL
#>  Processing record $THETA
#>  Processing record $OMEGA
#>  Processing record $SIGMA
#>  Processing record $PROBLEM
#>  Processing record $DATA
#>  Processing record $SUBROUTINES
#>  Processing record $PK
#>  Processing record $DES
#>  Processing record $ERROR
#>  Processing record $ESTIMATION
#>  Ignore record $ESTIMATION
#>  Processing record $COVARIANCE
#>  Ignore record $COVARIANCE
#>  Processing record $TABLE
#>  change initial estimate of `theta1` to `1.37034036528946`
#>  change initial estimate of `theta2` to `4.19814911033061`
#>  change initial estimate of `theta3` to `1.38003493562413`
#>  change initial estimate of `theta4` to `3.87657341967489`
#>  change initial estimate of `theta5` to `0.196446108190896`
#>  change initial estimate of `eta1` to `0.101251418415006`
#>  change initial estimate of `eta2` to `0.0993872449483344`
#>  change initial estimate of `eta3` to `0.101302674763154`
#>  change initial estimate of `eta4` to `0.0730497519364148`
#>  read in nonmem input data (for model validation): /home/runner/work/_temp/Library/nonmem2rx/mods/cpt/Bolus_2CPT.csv
#>  ignoring lines that begin with a letter (IGNORE=@)'
#>  applying names specified by $INPUT
#>  subsetting accept/ignore filters code: .data[-which((.data$SD == 0)),]
#>  done
#>  read in nonmem IPRED data (for model validation): /home/runner/work/_temp/Library/nonmem2rx/mods/cpt/runODE032.csv
#>  done
#>  changing most variables to lower case
#>  done
#>  replace theta names
#>  done
#>  replace eta names
#>  done (no labels)
#>  renaming compartments
#>  done
#>  solving ipred problem
#>  done
#>  solving pred problem
#>  done

Step 2: convert the rxode2 model to nlmixr2

In this step, you convert the model to nlmixr2 by as.nlmixr2(mod); You may need to do a little manual work to get the residual specification to match between nlmixr2 and NONMEM.

Once the residual specification is compatible with a nlmixr2 object, you can convert the model, mod, to a nlmixr2 fit object:

fit <- as.nlmixr2(mod)
#> → loading into symengine environment...
#> → pruning branches (`if`/`else`) of full model...
#>  done
#> → finding duplicate expressions in EBE model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → optimizing duplicate expressions in EBE model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → compiling EBE model...
#>  done
#> rxode2 2.1.0 using 2 threads (see ?getRxThreads)
#>   no cache: create with `rxCreateCache()`
#> → Calculating residuals/tables
#>  done
#> → compress origData in nlmixr2 object, save 204016
#> → compress parHistData in nlmixr2 object, save 2184

fit

\[\begin{align*} cmt({CENTRAL}) \\ cmt({PERI}) \\ {cl} & = \exp\left({theta1}+{eta1}\right) \\ {v} & = \exp\left({theta2}+{eta2}\right) \\ {q} & = \exp\left({theta3}+{eta3}\right) \\ {v2} & = \exp\left({theta4}+{eta4}\right) \\ {v1} & = {v} \\ {scale1} & = {v} \\ {k21} & = \frac{{q}}{{v2}} \\ {k12} & = \frac{{q}}{{v}} \\ \frac{d \: CENTRAL}{dt} & = {k21} {\times} {PERI}-{k12} {\times} {CENTRAL}-\frac{{cl} {\times} {CENTRAL}}{{v1}} \\ \frac{d \: PERI}{dt} & = -{k21} {\times} {PERI}+{k12} {\times} {CENTRAL} \\ {f} & = \frac{{CENTRAL}}{{scale1}} \\ {ipred} & = {f} \\ {rescv} & = {RSV} \\ {ipred} & \sim prop({RSV}) \end{align*}\]

Step 3: Create a PowerPoint file

A PowerPoint can be created from your own custom powerpoint templates, but in this example we will use the ones that come from nlmixr2rpt directly:

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)
#> 
#> Attaching package: 'xpose'
#> The following object is masked from 'package:stats':
#> 
#>     filter
#> Registered S3 method overwritten by 'GGally':
#>   method from   
#>   +.gg   ggplot2
#> 
#> Attaching package: 'ggPMX'
#> The following object is masked from 'package:xpose':
#> 
#>     get_data
#> → loading into symengine environment...
#> → pruning branches (`if`/`else`) of full model...
#>  done
#> → calculate jacobian
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → calculate sensitivities
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → calculate ∂(f)/∂(η)
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → calculate ∂(R²)/∂(η)
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → finding duplicate expressions in inner model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → optimizing duplicate expressions in inner model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → finding duplicate expressions in EBE model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → optimizing duplicate expressions in EBE model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → compiling inner model...
#> using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’
#>  done
#> → finding duplicate expressions in FD model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → optimizing duplicate expressions in FD model...
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
#> → compiling EBE model...
#> using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’
#>  done
#> → compiling events FD model...
#> using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’
#>  done
#> → Calculating residuals/tables
#>  done
#> Warning in xpose.nlmixr2::xpose_data_nlmixr(fit): Added CWRES to fit (using
#> nlmixr2::addCwres)...
#> Skipping table: skip_table (NA found, not generated)
#> Skipping figure: res_vs_pred_idv (NA found, not generated)
#> Skipping figure: eta_cont (NA found, not generated)
#> Skipping figure: eta_cat (NA found, not generated)
#> Skipping figure: skip_figure (NA found, not generated)

save_report(obnd_pptx, "mod-PowerPoint.pptx")
#> $isgood
#> [1] TRUE
#> 
#> $msgs
#> NULL

Which gives the powerpoint here

Step 4: Create a Word file

Just like in PowerPoint, you can customizeown custom word templates, but in this example we will use the ones that come from nlmixr2rpt directly:

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)
#> → Calculating residuals/tables
#>  done
#> Warning in xpose.nlmixr2::xpose_data_nlmixr(fit): Added CWRES to fit (using
#> nlmixr2::addCwres)...
#> Skipping figure: res_vs_pred_idv (NA found, not generated)
#> Skipping figure: skip_figure (NA found, not generated)
#> Skipping figure: eta_cont (NA found, not generated)
#> Skipping figure: eta_cat (NA found, not generated)

save_report(obnd_docx, "mod-Word.docx")
#> $isgood
#> [1] TRUE
#> 
#> $msgs
#> NULL

Which gives the word document here