library(mrgsolve)
library(readr)
library(dplyr)
1 Introduction
mrgsolve version 1.0.8 was released to CRAN on March 4th, 2023. This blog post introduces some of the new features in 1.0.8 as well as 1.0.7, which was not released to CRAN.
2 Missing values and input data sets
Missing values (NA
) are now allowed in the following columns of input data sets:
CMT
AMT
RATE
EVID
II
ADDL
SS
The lower case versions of these names may also include NA
.
cmt
amt
rate
evid
ii
addl
ss
In previous versions of mrgsolve, it was an error to include NA
in these data set columns. Starting with version 1.0.7, mrgsolve will convert NA
to 0
for these columns only. mrgsolve will continue to warn the user when missing values are in parameter columns.
3 Convenient ETA capture
The $CAPTURE
block gains a new option for capturing any or all ETA
s into the simulated output. The user writes an expression which evaluates to the integer numbers of ETA
s to capture into the @etas
option. For example
0.1 0.2 0.3
$OMEGA
1:LAST
$CAPTURE @etas CL Y
will capture ETAs 1, 2, and 3 into ETA1
, ETA2
, and ETA3
in the simulated output.
Note that the syntax resembles what you might write in NONMEM where last
is the total number of ETA
s in the problem.
Note also that ETA
naming resembles what you would get from NONMEM. This is contrasted with the naming that you continue to get when you simply capture ETA(1)
$CAPTURE (1) CL Y ETA
In this case, the name would be ETA_1
, with ()
getting removed and replaced with _
. This sanitization of names happens any time a captured item has parens or brackets in the name.
4 New model macro: SIGMA()
The user can now access on-diagonal elements of $SIGMA
through the SIGMA()
macro. For example
0.1 12
$SIGMA
$TABLEdouble STD=sqrt(SIGMA(1)+pow(F,2)*SIGMA(2));
This macro provides read-only access to the $SIGMA
elements.
5 Matching mrgsolve and NONMEM run numbers
When a mrgsolve model is translated from a NONMEM run, it is common to give them matching file names. For example, if 101.ctl
is the NONMEM control stream name, we might create an mrgsolve version of that run as 101.cpp
or 101.mod
.
In this case, we will likely use $NMEXT
or $NMXML
blocks to import the estimates from the completed NONMEM run with code like this
$NMEXT= 101
run = "model/nonmem" project
if the run completed in the model/nonmem
directory.
Starting with mrgsolve version 1.0.7, users can assume this connection in run numbers by setting the run
to @cppstem
$NMEXT= "@cppstem"
run = "model/nonmem" project
This tells $NMEXT
(and $NMXML
) to look for 101.ext
(or 101.xml
) in the model/nonmem/101
directory. Using this syntax will relieve the user from having to update the run number in these blocks when forking one model file to match a new NONMEM run.
6 Scrape ETAs from the input data set
mrgsim()
gains a new argument called etasrc
which allows you to look to the data set for ETA
s rather than simulating them from $OMEGA
. This feature has several applications, including validation of your model translation from NONMEM and simulating from empirical Bayes estimates. These topics will be covered more in depth in separate blog posts.
For now, let’s look at an example. This model has three ETAs
<- mcode("etas",
mod '
$OMEGA 1 2 3
$CAPTURE @etas 1:last
',
end = 3
)
By default, the ETA
s are random draws from $OMEGA
mrgsim(mod, end = -1, nid = 4)
Model: etas
Dim: 4 x 5
Time: 0 to 0
ID: 4
ID time ETA1 ETA2 ETA3
1: 1 0 -0.08064 0.2625 0.4160
2: 2 0 0.22828 0.9758 -1.5180
3: 3 0 0.45809 3.0437 0.8761
4: 4 0 -1.45897 -0.2954 0.1237
When you have ETA
s coded into your data set
<- expand.ev(cmt = 0, ETA1 = 0.1, ETA2 = 0.2, ETA3 = 0.3)
data data
ID time amt cmt evid ETA1 ETA2 ETA3
1 1 0 0 0 1 0.1 0.2 0.3
you can ask mrgsolve to use the data set ETA
s rather than simulating new ones
mrgsim(mod, data, etasrc = "data")
Model: etas
Dim: 5 x 5
Time: 0 to 3
ID: 1
ID time ETA1 ETA2 ETA3
1: 1 0 0.1 0.2 0.3
2: 1 0 0.1 0.2 0.3
3: 1 1 0.1 0.2 0.3
4: 1 2 0.1 0.2 0.3
5: 1 3 0.1 0.2 0.3
If the data set is missing one of the ETA
s, it will be filled with 0
<- select(data, -ETA2)
miss2
mrgsim(mod, miss2, etasrc = "data")
Model: etas
Dim: 5 x 5
Time: 0 to 3
ID: 1
ID time ETA1 ETA2 ETA3
1: 1 0 0.1 0 0.3
2: 1 0 0.1 0 0.3
3: 1 1 0.1 0 0.3
4: 1 2 0.1 0 0.3
5: 1 3 0.1 0 0.3
You can ask for an error to be generated if not all ETA
s are found on the data set by using etasrc = "data.all"
try(mrgsim(mod, miss2, etasrc = "data.all"))
Error : all 3 ETAs must be provided when `etasrc` is "data.all".
Also, an error will be generated if you ask for ETA
s from the data set, but there are none
<- select(data, -contains("ETA"))
missall
try(mrgsim(mod, missall, etasrc = "data"))
Error : at least one ETA must be provided when `etasrc` is "data".
You can get more information about the etasrc
argument in the ‘Details’ section of the mrgsim()
help page.
?mrgsim