Tutorials › Pharmacometric Workflows and Reproducible Modeling › mrgsolve Model Files and R Interfaces

Software Landscape and Interoperability · Tutorial 196 of 399

mrgsolve Model Files and R Interfaces

Learn to read and build a basic mrgsolve model file, run it from R, and check that its simulated concentration profile is consistent with the model assumptions.

Intermediate 10 min read

What You'll Learn

  • Identify the roles of key mrgsolve blocks, including $PARAM, $INIT, $ODE, $TABLE and $CAPTURE.
  • Connect a central-compartment amount state to its differential equation and a reported concentration.
  • Compile a model file and simulate an intravenous bolus from R.
  • Check simulated concentrations against the corresponding analytic solution.
  • Diagnose common model-file, unit, parameter and output errors.

From Model Description to a Runnable mrgsolve File

A pharmacometric model is not only a set of equations. It must also specify what quantities the software treats as parameters, how its dynamic states begin, how those states change over time, and which calculated quantities should be returned to the analyst. In mrgsolve, these tasks are organized into named blocks in a model file, which is compiled and controlled through R.

This tutorial focuses on the file structure and the R interface. The example is deliberately small: a single central compartment after an intravenous bolus. Its purpose is to show how model components connect and how to check a run, not to develop an estimation workflow. The model assumes a fixed dose, fixed positive clearance and volume, first-order elimination, and no absorption, random effects, or residual error.

Definition: In an mrgsolve model, a parameter is a supplied quantity used by the model equations; a state is a quantity that changes over time and is integrated by the solver; an initial condition gives a state’s value at the start of simulation; and a captured output is a quantity made available in the simulation results. A model block assigns one or more of these roles to code or declarations in the model file.

The block names are part of the model’s interface, not decorative headings. For this example, $PARAM supplies clearance and volume, $INIT sets the starting central amount, $ODE defines its time derivative, and $TABLE with $CAPTURE defines and returns plasma concentration. A $PROB block can label the model for a human reader. A compact file can omit blocks that are not needed.

States, Parameters, and the Differential Equation

Let \(A(t)\) denote the amount of drug in the central compartment at time \(t\), measured in mg. Let \(CL\) be clearance in L/h and \(V\) be volume in L. With linear elimination, the rate of loss of amount is clearance multiplied by concentration. Since concentration is \(A(t)/V\), the differential equation is

$$ \frac{dA(t)}{dt}=-CL\frac{A(t)}{V} =-\frac{CL}{V}A(t). $$

The ratio \(CL/V\) has units \(h^{-1}\), so multiplying it by an amount in mg gives a rate in mg/h, as required for the derivative of amount with respect to time. The concentration reported at any time is \(CP(t)=A(t)/V\), in mg/L. These units are part of the model specification: if a dose is entered in mg but volume is supplied in mL without conversion, the resulting concentration will be wrong by a factor of 1,000.

A minimal model file can be written as the following sequence of blocks. The block contents are shown as separate lines; they belong together in one model source file.

$PROB One-compartment bolus demonstration

$PARAM CL = 5, V = 50

$INIT CENT = 0

$ODE

dxdt_CENT = -(CL/V)*CENT;

$TABLE

double CP = CENT/V;

$CAPTURE CP

Here CENT is the state corresponding to \(A(t)\). The derivative name begins with dxdt_ followed by the state name, so dxdt_CENT specifies the rate of change of CENT. The parameter values 5 L/h and 50 L imply an elimination rate constant of \(5/50=0.1\ h^{-1}\). The initial condition is zero because the system is empty before the dose. The dose is supplied as an event from R, rather than written into the initial-condition block.

The $PARAM values are defaults that can be changed when configuring a model in R. They are not automatically estimates, covariates, or random effects. The $TABLE block calculates a derived quantity after the state has been updated for the relevant time, and $CAPTURE makes CP available as a result column. Capturing a quantity does not alter the differential equation.

Worked Example: Translating the Model Into Blocks

Suppose the intended simulation uses a 100 mg intravenous bolus, \(CL=5\) L/h and \(V=50\) L. Identify the model-file role of each quantity before running anything.

Parameters. Clearance and volume appear in the right-hand side of the differential equation, so they belong in $PARAM. Their ratio is \(CL/V=(5\ \mathrm{L/h})/(50\ \mathrm{L})=0.1\ h^{-1}\).

State and initial condition. The changing quantity is central amount CENT, in mg. It begins at \(0\) mg under the assumption that the compartment is empty before dosing, so $INIT CENT = 0 is appropriate.

Differential equation. Substitution gives \(dCENT/dt=-(0.1\ h^{-1})CENT\). When CENT is 100 mg immediately after the bolus, its instantaneous derivative is \(-(0.1\ h^{-1})(100\ \mathrm{mg})=-10\ \mathrm{mg/h}\), a negative rate consistent with elimination.

Reported quantity. Concentration is calculated from the state and volume: \(CP=CENT/V\). At 100 mg and 50 L, \(CP=100/50=2\ \mathrm{mg/L}\). The concentration is a derived output; CENT remains the integrated state.

Compiling and Simulating From R

Save the model text in a source file named pk1.cpp in the working project directory. With mrgsolve installed, load the package and read the model by its name without the file extension. The following R commands compile the model and request output every hour through 24 hours:

library(mrgsolve)

mod <- mread("pk1", project = ".")

out <- mrgsim(mod, events = ev(amt = 100, cmt = 1), end = 24, delta = 1)

result <- as.data.frame(out)

In this event, amt is the dose amount in the model’s amount units and cmt = 1 identifies the first declared state, CENT. The event is an intravenous bolus. The simulation horizon is 24 hours, and delta = 1 requests hourly output. The resulting data frame includes time, the state CENT, and the captured quantity CP. A dose event changes the state; it is not a parameter declaration or a new differential equation.

The model can also be configured with new parameter values in R. For example, param(mod, CL = 6) creates a model configuration with clearance changed to 6 while retaining the other parameter value. The event and simulation settings can then be supplied to mrgsim again. Keep a record of which model configuration and event data generated each result; otherwise, a plausible output can still be associated with the wrong settings.

Worked Example: Checking the Baseline Simulation Analytically

For the hypothetical 100 mg bolus with \(CL=5\) L/h and \(V=50\) L, the initial post-dose amount is \(A(0)=100\) mg. The model assumes a single compartment and first-order elimination, so the differential equation has a closed-form solution.

Derivation. Separate variables in \(dA/dt=-kA\), where \(k=CL/V\): \(dA/A=-k\,dt\). Integrating from time 0 to \(t\) gives \(\ln(A(t))-\ln(A(0))=-kt\). Exponentiating both sides yields \(A(t)=A(0)e^{-kt}\). Dividing by volume gives

$$ CP(t)=\frac{A(0)}{V}e^{-(CL/V)t}. $$

Here \(k=5/50=0.1\ h^{-1}\), and \(A(0)/V=100/50=2\) mg/L. At 12 hours,

$$ CP(12)=\frac{100\ \mathrm{mg}}{50\ \mathrm{L}} e^{-(0.1\ \mathrm{h}^{-1})(12\ \mathrm{h})} =2e^{-1.2}\ \mathrm{mg/L} \approx 0.6024\ \mathrm{mg/L}. $$

At 24 hours,

$$ CP(24)=2e^{-(0.1)(24)}\ \mathrm{mg/L} =2e^{-2.4}\ \mathrm{mg/L} \approx 0.1814\ \mathrm{mg/L}. $$

Compare these analytic values with the rows at times 12 and 24 in result. Small differences can arise from numerical integration tolerances; a large discrepancy suggests checking the dose amount and compartment, time units, parameter values, and the concentration calculation. The comparison is a model implementation check, not evidence that the model describes any real patient.

Numerical Checks and Failure Modes

A simulation is useful only if its output is consistent with the source model and the intended inputs. For this one-compartment bolus example, several checks follow directly from the stated assumptions. After the dose, CENT should be nonnegative and decline monotonically because \(dCENT/dt=-(CL/V)CENT\) is negative whenever \(CL>0\), \(V>0\), and CENT is positive. CP should equal CENT divided by V at every output time. If clearance is zero, the state should remain constant after the bolus; if volume increases with clearance unchanged, the initial concentration should decrease.

1
Check compilation and declarations.
Confirm that the model file is found, block names are spelled correctly, and every parameter and state used in the equations is declared.
2
Check event mapping and units.
Verify the dose amount, the compartment index, the dose time, and that amount, clearance, volume, and time use compatible units.
3
Check the trajectory.
Inspect several output rows, not only the final value. Confirm the expected direction of change and that CP agrees with CENT/V.
4
Check an independent reference.
For the simple bolus model, compare selected simulated concentrations with the analytic expression. If a discrepancy remains, reduce the model to a minimal case before adding complexity.

Common failures have recognizable patterns. A compiler error often means a typo, missing declaration, or malformed block. A run that completes but has no meaningful dose response can result from an event assigned to the wrong compartment. Concentrations off by a constant factor often indicate a unit mismatch or a mistaken volume. A flat profile despite positive clearance can signal that the state derivative was omitted or named incorrectly. Output lacking CP may mean the calculated variable was not captured. Solver warnings or unstable values call for checking the equations and units, parameter ranges, and integration settings rather than simply accepting the output.

Worked Example: Changing Clearance and Checking the Direction

Now change only clearance to \(6\) L/h, leaving dose at 100 mg and volume at 50 L. The rate constant is \(6/50=0.12\ h^{-1}\). The initial post-dose concentration remains \(100/50=2\) mg/L because dose and volume did not change.

At 12 hours, the model predicts

$$ CP(12)=2e^{-(0.12)(12)}\ \mathrm{mg/L} =2e^{-1.44}\ \mathrm{mg/L} \approx 0.4739\ \mathrm{mg/L}. $$

At 24 hours, it predicts

$$ CP(24)=2e^{-(0.12)(24)}\ \mathrm{mg/L} =2e^{-2.88}\ \mathrm{mg/L} \approx 0.1123\ \mathrm{mg/L}. $$

Both values are below the corresponding baseline values, 0.6024 mg/L and 0.1814 mg/L, because the larger clearance increases the elimination rate while the dose and volume stay fixed. If an R run instead produced a higher concentration at these times, check that the changed parameter was passed to the model actually simulated and that no other setting changed.

Choosing the Right Level of Model Complexity

A useful alternative to a source model is a model assembled through an R interface or a higher-level modeling language. Such tools can be more convenient for defining estimation problems, data mappings, and model structures. mrgsolve is particularly direct when the goal is to specify a dynamic system and simulate it with explicit model code. The best choice depends on the task; the syntax is not itself evidence that one model is more scientifically appropriate than another.

The compact example also makes its limitations clear. It represents a single bolus and a single amount state, with fixed parameters and no measurement error. It does not establish how a dataset should be prepared, how parameters should be estimated, or how more complex dosing records and model features should be translated. Those additions change the model and its assumptions, so they should be introduced only when required and checked individually.

Common pitfall: Treating a successful compilation as proof that the model is correct. A model can compile while using the wrong dose compartment, inconsistent units, an incorrect derivative, or an uncaptured output. Check the model’s declarations, event mapping, units, trajectory, and an independent calculation before relying on the results.

Check Your Understanding

Answer each question, then compare your reasoning with the solutions below.

  1. In the example file, which block supplies CL and V, and which block specifies the rate of change of CENT?
  2. If the dose is 150 mg and volume is 50 L, what is the immediate post-dose concentration under the model assumptions?
  3. With \(CL=5\) L/h and \(V=50\) L, what is the elimination rate constant, and what are its units?
  4. Why is CP a captured output rather than the state being integrated in this example?
  5. Name two checks that can help identify a dose-mapping or unit error in an apparently successful run.

Solutions. 1. $PARAM supplies CL and V; $ODE defines the derivative dxdt_CENT. 2. \(150\ \mathrm{mg}/50\ \mathrm{L}=3\ \mathrm{mg/L}\). 3. \(CL/V=(5\ \mathrm{L/h})/(50\ \mathrm{L})=0.1\ h^{-1}\). 4. The differential equation evolves the central amount CENT; concentration is calculated from that state as CENT/V and returned through $CAPTURE. 5. Check the dose amount and cmt assignment, verify compatible units, inspect whether CENT changes in the expected direction, and compare selected concentrations with the analytic solution.

Clinical Biostats