@param begin
∈ RealDomain(lower = 0, init = 5) # Typical value of Clearance
TVCL ∈ RealDomain(lower = 0, init = 50) # Typical value of Volume
TVV ∈ PDiagDomain(2) # Variance for IIV
Ω ∈ RealDomain(lower = 0, init = 0.1) # Variance for IOV of Clearance
Ω_IOV_CL ∈ RealDomain(lower = 0, init = 0.1) # Variance for IOV of Volume
Ω_IOV_Vc ∈ RealDomain(lower = 0, init = 0.1) # Proportional error
σ_prop end
@covariates OCC
@random begin
~ MvNormal(Ω)
η ~ MvNormal(Diagonal(fill(Ω_IOV_CL, 7)))
κCL ~ MvNormal(Diagonal(fill(Ω_IOV_Vc, 7)))
κVc end
@pre begin
= TVCL * exp(η[1] + κCL[OCC])
CL = TVV * exp(η[2] + κVc[OCC])
Vc end
Understanding Correlated Interoccasion Variability (IOV) Modeling in Pumas
The tutorial on Modeling Interoccasion Variability (IOV) in PKPD Models using Pumas teaches how to model random effects that vary between occasions. In that situation there is a random effect κ
that has one element per occasion and for each occasion it has the same variance Ω_IOV
. Instead of writing out 7 different random effect definitions they were collected in one big multivariate random effect using a Diagonal
matrix to represent the structure of the variance covariance matrix.
In the case where there is not one random effect that varies across occasions but several the workflow has to be adjusted slightly. This tutorial will introduce a more general approach to using a Diagonal
matrix in the univariate occasion random effect case using a BlockDiagonal
that allows us to represent the repeated covariance structure between the random effects.
1 Prerequisites
Before we begin, ensure that you have:
- Familiarity with the basics of nonlinear mixed-effects modeling (NLME) in Pumas including parameter and random effect specification
- A working knowledge of IOV modeling concepts in Pumas based on the previous tutorial
- The package
BlockDiagonals.jl
installed.using BlockDiagonals
will load the package or ask you to install it if it’s not already installed.
3 Complete Example
3.1 The model
Putting it all together, here’s the full model code:
using Pumas, BlockDiagonals
= @model begin
IOV_PK_model @param begin
∈ RealDomain(lower = 0, init = 5) # Typical value of Clearance
TVCL ∈ RealDomain(lower = 0, init = 50) # Typical value of Volume
TVV ∈ PDiagDomain(2) # Variance for IIV
Ω ∈ PSDDomain(2 * 7) # Variance-Covariance for IOV
Ω_IOV ∈ RealDomain(lower = 0, init = 0.1) # Proportional error
σ_prop end
@covariates OCC
@random begin
~ MvNormal(Ω)
η ~ MvNormal(BlockDiagonal(fill(Ω_IOV, 7)))
κ end
@pre begin
= TVCL * exp(η[1] + κ[OCC*2-1])
CL = TVV * exp(η[2] + κ[OCC*2])
Vc end
@dynamics Central1
@derived begin
= @. Central / Vc
cp ~ @. Normal(cp, abs(cp) * σ_prop)
dv end
end
PumasModel
Parameters: TVCL, TVV, Ω, Ω_IOV, σ_prop
Random effects: η, κ
Covariates: OCC
Dynamical system variables: Central
Dynamical system type: Closed form
Derived: cp, dv
Observed: cp, dv
The key things to notice are:
Ω_IOV
is now aPSDDomain
so the input to any simulation or fitting procedure must be a 2x2 matrix. This is true even if there are more or less occasions as we only parameterize each block we do not estimate the entire variance covariance matrix as if all elements are free.- We use
BlockDiagonal
instead ofDiagonal
in theMvNormal
specification - We need to input a vector of matrices to
BlockDiagonal
so we now usefill
to create a vector of 7 elements where each element is a 2x2 matrix
3.2 The Design
= map(
pop1 -> Subject(
subj = subj,
id = DosageRegimen(100, addl = 6, ii = 24),
events = (; OCC = [1, 2, 3, 4, 5, 6, 7]),
covariates = [0, 24, 48, 72, 96, 120, 144],
covariates_time = (; dv = nothing),
observations
),1:10,
)
Population
Subjects: 10
Covariates: OCC
Observations: dv
3.3 The Parameters
= (TVCL = 4, TVV = 10, Ω = [0.04, 0.04], Ω_IOV = [0.4 0.01; 0.01 0.5], σ_prop = 0.2) params
(TVCL = 4,
TVV = 10,
Ω = [0.04, 0.04],
Ω_IOV = [0.4 0.01; 0.01 0.5],
σ_prop = 0.2,)
3.4 Simulate
using Random
Random.seed!(1234)
= simobs(IOV_PK_model, pop1, params, obstimes = 0:1:192) sims
Simulated population (Vector{<:Subject})
Simulated subjects: 10
Simulated variables: cp, dv
3.5 Plot
using PumasUtilities
sim_plot(sims, observations = [:cp])
4 Conclusion
Modeling interoccasion variability in Pumas is straightforward once you understand the concepts:
- Shared Variance-Covariance: By sharing a variance-covariance matrix
Ω_IOV
across occasions, we ensure that the variability and correlation is the same across occasions. - Indexing: Using the occasion covariate (
OCC
) to index several IOV random effects allows each occasion to have unique effects while maintaining shared distributional assumptions. - Implementation: Pumas provides a flexible framework to incorporate IOV into your models with minimal additional code.
Note: Always ensure that your data includes an appropriate occasion covariate and that it’s correctly specified in your Pumas model. This is especially true when introducing covariances as there is typically not a lot of data in each occasion to estimate these.