Writing Your First nlmixr2 Model

Translate structural PK thinking into the nlmixr2 modeling framework.
Tip

Big picture: nlmixr2 does not introduce new PK concepts. It provides a structured way to express structural assumptions and prepare them for estimation.

Learning Objectives

By the end of this lesson, you will be able to:

  • Explain the structure of an nlmixr2 model.
  • Understand ini() and model() blocks.
  • Translate structural parameters into nlmixr2 syntax.
  • Recognize how random effects enter the model.
  • Write a complete first PK model.

Key Ideas

  • nlmixr2 separates parameter initialization from model definition.
  • Structural concepts remain unchanged.
  • Random effects represent subject variability.
  • Residual error represents unexplained variability.

Setup

library(tidyverse)
library(nlmixr2)
library(nlmixr2data)

data("theo_sd", package = "nlmixr2data")

obs <-
  theo_sd %>%
  filter(EVID == 0)

From Structural Thinking to Software

In the previous module we wrote:

one_comp_oral(time, dose, ka, CL, V)

That expressed:

Dose

↓

Parameters

↓

Prediction

Now we write the same idea inside nlmixr2.


Worked Example 1: Smallest Valid nlmixr2 Model

one_comp_model <- function(){

  ini({

    tka <- log(1)

    tcl <- log(3)

    tv <- log(30)

  })

  model({

    ka <- exp(tka)

    cl <- exp(tcl)

    v <- exp(tv)

    linCmt() ~ add(0.1)

  })

}

This is a complete model definition.

Nothing has been estimated yet.


Worked Example 2: Understanding ini()

The ini() block defines initial values.

ini({

  tka <- log(1)

  tcl <- log(3)

  tv <- log(30)

})

Interpretation:

Parameter Meaning
tka typical absorption
tcl typical clearance
tv typical volume

These values act as starting points.

They are not final estimates.


Worked Example 3: Understanding model()

The model() block defines how predictions are generated.

model({

  ka <- exp(tka)

  cl <- exp(tcl)

  v <- exp(tv)

  linCmt() ~ add(0.1)

})

Interpretation:

  • convert parameters to positive values
  • generate concentrations
  • define residual variability

Notice that the parameters are stored on the log scale:

tka <- log(1)
tcl <- log(3)
tv <- log(30)

and then transformed back using:

ka <- exp(tka)
cl <- exp(tcl)
v <- exp(tv)

This approach guarantees that PK parameters remain positive.

For example:

Clearance > 0
Volume > 0
Absorption Rate > 0

which is biologically reasonable and often improves numerical stability during estimation.

Do not focus on exact syntax yet.

This block simply tells nlmixr2:

  • how concentrations are generated
  • how variability will later be represented

Individual pieces will be introduced in later modules.


Worked Example 4: Where Random Effects Will Appear

Population models eventually extend parameters.

Example:

ka <- exp(tka + eta.ka)

Conceptually:

Log(Typical Value)
+
Subject Deviation
↓
Exponentiate
↓
Positive Individual Parameter

For example:

Typical CL = 3

eta.cl = 0.2

Individual CL = exp(log(3) + 0.2)
              = 3.66

A positive random effect increases the parameter.

A negative random effect decreases the parameter.

The exponentiation step ensures the parameter remains positive.

At this stage:

focus on understanding the idea.


Worked Example 5: Connecting Back to the Structural Model

Compare.

Structural model:

Dose
↓
ka CL V
↓
Concentration

Population model:

Dose

↓

Typical Parameters

↓

Subject Variability

↓

Concentration

The structure remains the same.


Strategies

  • Read models top to bottom.
  • Connect syntax to PK meaning.
  • Ignore optimization details for now.

Common Mistakes

  • Memorizing syntax.
  • Ignoring parameter meaning.
  • Treating nlmixr2 as magic.

Practice Problems

  1. What does the ini() block define?

  2. What does the model() block define?

  3. Why are exp() transformations commonly used?

  4. Run the model object.

one_comp_model()

What is returned?

  1. Modify one starting value.

Change:

tcl <- log(3)

to:

tcl <- log(5)

Does this change estimate the model?


Problem 1

ini() defines starting parameter values.

These values initialize estimation and are not final estimates.

Examples:

  • typical parameters
  • variability
  • residual error

Problem 2

model() defines how parameters generate predictions.

Conceptually:

Parameters

↓

Concentration Prediction

Problem 3

exp() ensures parameters remain positive.

For example:

CL > 0
V > 0
ka > 0

This also improves numerical behavior.


Problem 4

Running:

one_comp_model()

returns a model specification object.

It defines:

  • initial values
  • equations
  • observation model

No estimation occurs.


Problem 5

Changing:

tcl <- log(3)

to:

tcl <- log(5)

changes the initial guess.

It does not estimate the model.

Estimation occurs later.


Summary

  • nlmixr2 expresses structural assumptions.
  • ini() defines starting values.
  • model() defines predictions.
  • Estimation begins in the next lesson.

  • Concepts first.
  • Syntax second.
  • Read models top to bottom.