new_ode_model
is the function that creates a new ODE
model that can be used in the sim()
command. It defines the
ODE system and sets some attributes for the model. The model can be
specified in three different ways:
model
: a string that references a model from the
library included in PKPDsim
. Examples in the current
library are e.g. pk_1cmt_oral
, pk_2cmt_iv
. To
show the available models, run new_ode_model()
without any
arguments.code
: using code specifying derivatives for ODE
specified in pseudo-R codefile
: similar to code
, but reads the code
from a fileFor example, a 1-compartment oral PK model can be obtained using:
Run the new_ode_model()
function without arguments to
see the currently available models:
## Error in new_ode_model(): Either a model name (from the PKPDsim library), ODE code, an R function, or a file containing code for the ODE system have to be supplied to this function. The following models are available:
## pk_1cmt_iv
## pk_1cmt_iv_auc
## pk_1cmt_iv_mm
## pk_2cmt_iv
## pk_2cmt_iv_auc
## pk_3cmt_iv
## pk_1cmt_oral
## pk_2cmt_oral
## pk_3cmt_oral
The custom model needs to be specified as a string or text block:
The input code should adhere to the follow rules:
dAdt
omputate[ ]
. Compartments indices can start at either 0 or 1.
If the latter, all indices will be reduced by 1 in the translation to
C++ code.=
pow(base,exp)
.real
, to avoid
them being interpreted as integer
. So if an equation
involves the real number 3
, it is usually safer to write
this as 3.0
in code.The input code is translated into a C++ function. You can check that the model compiled correctly by typing the model name on the R command line, which prints the model information:
## ODE definition:
##
## dAdt[1] = -KA * A[1];
## dAdt[2] = +KA * A[1] -(CL/V) * A[2];
## ;
##
## Required parameters: KA, CL, V
## Covariates:
## Variables:
## Fixed parameters:
## Number of compartments: 2
## Observation variable:
## Observation scaling: 1
## Lag time: none
## IOV CV: {}
## IOV bins: 1
## Comments:
## -
If you’re interested, you can also output the actual C++ function
that is compiled by specifying the cpp_show_code=TRUE
argument to the new_ode_model()
function.
You can introduce new variables in your code, but you will have to
define them using declare_variables
argument too:
pk1 <- new_ode_model(code = "
KEL = CL/V
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -KEL * A[2]
", declare_variables = c("KEL"))
Also, when you want to use covariates in your ODE system (more info on how to define covariates is in the Covariates vignette), you will have to define them, both in the code and in the function call:
pk1 <- new_ode_model(code = "
CLi = WT/70
KEL = CLi/V
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -(CL*(WT/70)/V) * A[2]
", declare_variables = c("KEL", "CLi"), covariates = c("WT"))
One exception to the input code syntax is the definition of power
functions. PKPDsim
does not translate those from the
pseudo-R code to valid C++ syntax automatically. C/C++ does not
use the ^
to indicate power functions, but uses the
pow(value, base)
function instead, so for example an
allometric PK model should be written as:
pk1 <- new_ode_model(code = "
CLi = CL * pow((WT/70), 0.75)
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -(CLi/V) * A[2]
", declare_variables = c("CLi"))
The default dosing compartment and bioavailability can be specified
using the dose
argument. By default, the dose will go into
compartment 1
, with a bioavailability of 1
.
The bioav
element in the list can be either a number or a
character string referring a parameter.
pk1 <- new_ode_model(code = "
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -(CL/V) * A[2]
",
dose = list(cmt = 1, bioav = "F1"),
parameters = list(KA = 1, CL = 5, V = 50, F1 = 0.7)
)
Bioavailability can also be used for dosing based on mg/kg, since
that is not supported in new_regimen()
. The way to
implement this is by scaling the dose by the “weight” covariate using
the bioavailability:
The observation compartment can be set by specifying a list to the
obs
argument, with either the elements cmt
and
scale
, or variable
.
pk1 <- new_ode_model(code = "
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -(CL/V) * A[2]
",
obs = list(cmt = 2, scale = "V")
)
The scale
can be either a parameter or a number, the
cmt
can only be a number.
Note that the variables specified inside the differential equation block are not available as scaling parameters. E.g. for allometry you will have to redefine the scaled volume as follows:
pk1 <- new_ode_model(code = "
Vi = V * (WT/70)
dAdt[1] = -KA * A[1]
dAdt[2] = +KA * A[1] -(CL/Vi) * A[2]
",
obs = list(cmt = 2, scale = "V * (WT/70)")
)
Or define the observation using a variable: