The MCMC Procedure

Example 80.22 One-Compartment Model with Pharmacokinetic Data

(View the complete code for this example.)

A popular application of nonlinear mixed models is in the field of pharmacokinetics, which studies how a drug disperses through a living individual. This example considers the theophylline data from Pinheiro and Bates (1995). Serum concentrations of the drug theophylline, which is used to treat respiratory diseases, are measured in 12 subjects over a 25-hour period after oral administration. The data are as follows.

data theoph;
   input subject time conc dose;
   datalines;
 1  0.00  0.74 4.02
 1  0.25  2.84 4.02
 1  0.57  6.57 4.02
 1  1.12 10.50 4.02
 1  2.02  9.66 4.02
 1  3.82  8.58 4.02
 1  5.10  8.36 4.02
 1  7.03  7.47 4.02

   ... more lines ...   

12 24.15  1.17 5.30
;

A commonly used one-compartment model is based on the differential equations

StartLayout 1st Row 1st Column StartFraction d upper A 0 left-parenthesis t right-parenthesis Over d t EndFraction 2nd Column equals 3rd Column minus upper K Subscript a Baseline upper A 0 left-parenthesis t right-parenthesis 2nd Row 1st Column StartFraction d upper A left-parenthesis t right-parenthesis Over d t EndFraction 2nd Column equals 3rd Column upper K Subscript a Baseline upper A 0 left-parenthesis t right-parenthesis minus upper K Subscript e Baseline upper A left-parenthesis t right-parenthesis EndLayout

where upper K Subscript a is the absorption rate and upper K Subscript e is the elimination rate.

The initial values are

StartLayout 1st Row 1st Column upper A Subscript a Baseline left-parenthesis t equals 0 right-parenthesis 2nd Column equals 3rd Column x 2nd Row 1st Column upper A left-parenthesis t equals 0 right-parenthesis 2nd Column equals 3rd Column 0 EndLayout

where x is the dosage.

The expected concentration of the substance in the body is computed by dividing the solution to the ODE, upper A left-parenthesis t right-parenthesis, by Cl, the clearance,

StartLayout 1st Row 1st Column mu Subscript i Baseline left-parenthesis t right-parenthesis 2nd Column equals 3rd Column upper A Subscript i Baseline left-parenthesis t right-parenthesis slash upper C l 2nd Row 1st Column y Subscript i Baseline left-parenthesis t right-parenthesis 2nd Column tilde 3rd Column normal left-parenthesis mu Subscript i Baseline left-parenthesis t right-parenthesis comma sigma squared right-parenthesis EndLayout

where i is the subject index.

Pinheiro and Bates (1995) consider the following first-order compartment model for these data, where log left-parenthesis upper C l right-parenthesis and log left-parenthesis upper K Subscript a Baseline right-parenthesis are modeled using random effects to account for the patient-to-patient variability:

StartLayout 1st Row 1st Column upper C l Subscript i 2nd Column equals 3rd Column exp left-parenthesis beta 1 plus b Subscript i Baseline 1 Baseline right-parenthesis 2nd Row 1st Column upper K Subscript a Sub Subscript i 2nd Column equals 3rd Column exp left-parenthesis beta 2 plus b Subscript i Baseline 2 Baseline right-parenthesis 3rd Row 1st Column upper K Subscript e Sub Subscript i 2nd Column equals 3rd Column exp left-parenthesis beta 3 right-parenthesis EndLayout

Here the betas denote fixed-effects parameters and the b Subscript is denote random-effects parameters with an unknown covariance matrix.

Although there is an analytical solution to this set of differential equations, this example illustrates the use of a general ODE solver that does not require a closed-form solution. To use the ODE solver, you want to first define the set of differential equations in PROC FCMP and store the objective function, called OneComp, in a user library:

proc fcmp outlib=sasuser.funcs.PK;
   subroutine OneComp(t,y[*],dy[*],ka,ke);
   outargs dy;
   dy[1] = -ka*y[1];
   dy[2] = ka*y[1]-ke*y[2];
   endsub;
run;

The first argument of the OneComp subroutine is the time variable in the differential equation. The second argument is the with-respect-to variable, which can be an array in case a multidimensional problem is required. The third argument is an array that stores the differential equations. This dy argument must also be the OUTARGS variable in the subroutine. The subsequent variables are additional variables, depending on the problem at hand.

In the OneComp subroutine, you can define upper K Subscript a and upper K Subscript e as functions of beta 1, beta 2, and the random-effects parameter b 2. The dy[1] and dy[2] are the differential equation, with dy[1] storing d upper A Subscript a slash d t and dy[2] storing d upper A Subscript c slash d t.

The following PROC MCMC statements use the CALL ODE subroutine to solve the set of differential equations defined in OneComp and then use that solution in the construction of the likelihood function:


options cmplib=sasuser.funcs;

proc mcmc data=theoph nmc=10000 seed=27 outpost=theophO diag=none
   nthreads=8;
   ods select PostSumInt;
   array b[2];
   array muB[2] (0 0);
   array cov[2,2];
   array S[2,2] (1 0 0 1);

   array init[2] dose 0;
   array sol[2];

   parms beta1 -3.22 beta2 0.47 beta3 -2.45 ;
   parms cov {0.03 0 0 0.4};
   parms s2y;

   prior beta: ~ normal(0, sd=100);
   prior cov ~ iwish(2, S);
   prior s2y  ~ igamma(shape=3, scale=2);

   random b ~ mvn(muB, cov) subject=subject;
   cl   = exp(beta1 + b1);
   ka   = exp(beta2 + b2);
   ke   = exp(beta3);
   v    = cl/ke;
   call ode('OneComp',sol,init,0,time,ka,ke);
   mu   = (sol[2]/v);
   model conc ~ normal(mu,var=s2y);
run;

The INIT array stores the initial values of the two differential equations, with upper A Subscript a Baseline left-parenthesis t equals 0 right-parenthesis equals sans-serif d sans-serif o sans-serif s sans-serif e and upper A left-parenthesis t equals 0 right-parenthesis equals 0. The array is used as an input argument to the CALL ODE subroutine.

The RANDOM statement specifies two-dimensional random effects, b, with a multivariate normal prior. The first random effect, b1, enters the model through the clearance variable, cl. The second random effect, b2, is part of the differential equations. The CALL ODE subroutine solves the OneComp set of differential equations and returns the solution to the SOL array. The second array element, SOL[2], is the solution to upper A Subscript i Baseline left-parenthesis t right-parenthesis for every subject i at every time t.

Posterior summary statistics are reported in Output 80.22.1.

Output 80.22.1: Posterior Summary Statistics

The MCMC Procedure

Posterior Summaries and Intervals
Parameter N Mean Standard
Deviation
95% HPD Interval
beta1 10000 -3.1989 0.0780 -3.3553 -3.0609
beta2 10000 0.4244 0.1915 0.00824 0.7664
beta3 10000 -2.4589 0.0495 -2.5647 -2.3702
cov1 10000 0.1306 0.0634 0.0449 0.2477
cov2 10000 -0.00222 0.0952 -0.1874 0.1888
cov3 10000 -0.00222 0.0952 -0.1874 0.1888
cov4 10000 0.6230 0.3295 0.1778 1.2376
s2y 10000 0.5231 0.0720 0.3888 0.6639


In this problem, the closed-form solution of the ODE is known:

upper C Subscript i t Baseline equals StartFraction upper D k Subscript e Sub Subscript i Subscript Baseline k Subscript a Sub Subscript i Subscript Baseline Over upper C l Subscript i Baseline left-parenthesis k Subscript a Sub Subscript i Subscript Baseline minus k Subscript e Sub Subscript i Subscript Baseline right-parenthesis EndFraction left-bracket exp left-parenthesis minus k Subscript e Sub Subscript i Subscript Baseline t right-parenthesis minus exp left-parenthesis minus k Subscript a Sub Subscript i Subscript Baseline t right-parenthesis right-bracket plus e Subscript i t

You can manually enter the equation in PROC MCMC and use the following program to fit the same model:

proc mcmc data=theoph nmc=10000 seed=22 outpost=theophC;
   array b[2];

   array mu[2] (0 0);
   array cov[2,2];
   array S[2,2] (1 0 0 1);

   parms beta1 -3.22 beta2 0.47 beta3 -2.45 ;
   parms cov {0.03 0 0 0.4};
   parms s2y;

   prior beta: ~ normal(0, sd=100);
   prior cov ~ iwish(2, S);
   prior s2y  ~ igamma(shape=3, scale=2);

   random b ~ mvn(mu, cov) subject=subject;
   cl   = exp(beta1 + b1);
   ka   = exp(beta2 + b2);
   ke   = exp(beta3);
   pred = dose*ke*ka*(exp(-ke*time)-exp(-ka*time))/cl/(ka-ke);
   model conc ~ normal(pred,var=s2y);
run;

Because this program makes it unnecessary to numerically solve the ODE at every observation and every iteration, it runs much faster than the program that uses the CALL ODE subroutine. But few pharmacokinetic models have known solutions that enable you to do that.

Last updated: March 08, 2022