Skip to contents

Introduction

A different error model can be defined for multiple endpoints models (eg. PK-PD, parent-metabolite, blood-urine…).

An example can be seen below, utilizing the warfarin data and model (provided by Tomoo Funaki and Nick Holford) from the nlmixr documentation (https://nlmixr2.org/articles/multiple-endpoints.html).

warfarin PKPD model

mod_warfarin_nlmixr <- function() {
    ini({
      #Fixed effects: population estimates 
      THETA_ktr=0.106
      THETA_ka=-0.087
      THETA_cl=-2.03
      THETA_v=2.07
      THETA_emax=3.4
      THETA_ec50=0.00724
      THETA_kout=-2.9
      THETA_e0=4.57
      
      #Random effects: inter-individual variability
      ETA_ktr ~ 1.024695
      ETA_ka ~ 0.9518403
      ETA_cl ~ 0.5300943
      ETA_v ~ 0.4785394
      ETA_emax ~ 0.7134424
      ETA_ec50 ~ 0.7204165
      ETA_kout ~ 0.3563706
      ETA_e0 ~ 0.2660827
      
      #Unexplained residual variability
      cp.sd <- 0.144
      cp.prop.sd <- 0.15
      pca.sd <- 3.91
    })
    model({
      #Individual model and covariates
      ktr <- exp(THETA_ktr + ETA_ktr)
      ka <- exp(THETA_ka + ETA_ka)
      cl <- exp(THETA_cl + ETA_cl)
      v <- exp(THETA_v + ETA_v)
      emax = expit(THETA_emax + ETA_emax)
      ec50 =  exp(THETA_ec50 + ETA_ec50)
      kout = exp(THETA_kout + ETA_kout)
      e0 = exp(THETA_e0 + ETA_e0)
      
      #Structural model defined using ordinary differential equations (ODE)
      DCP = center/v
      PD=1-emax*DCP/(ec50+DCP)
      
      effect(0) = e0
      kin = e0*kout
      
      d/dt(depot) = -ktr * depot
      d/dt(gut) =  ktr * depot -ka * gut
      d/dt(center) =  ka * gut - cl / v * center
      d/dt(effect) = kin*PD -kout*effect
      
      cp = center / v
      pca = effect
      
      #Model for unexplained residual variability
      cp ~ add(cp.sd) + prop(cp.prop.sd)
      pca ~ add(pca.sd)
    })
  }

data: first subject from the warfarin dataset

warf_01 <- data.frame(ID=1,
                      TIME=c(0.0,1.0,3.0,6.0,24.0,24.0,36.0,36.0,48.0,48.0,72.0,72.0,144.0),
                      DV=c(0.0,1.9,6.6,10.8,5.6,44.0,4.0,27.0,2.7,28.0,0.8,31.0,71.0),
                      DVID=c("cp","cp","cp","cp","cp","pca","cp","pca","cp","pca","cp","pca","pca"),
                      EVID=c(1,0,0,0,0,0,0,0,0,0,0,0,0),
                      AMT=c(100,0,0,0,0,0,0,0,0,0,0,0,0))
warf_01
#>    ID TIME   DV DVID EVID AMT
#> 1   1    0  0.0   cp    1 100
#> 2   1    1  1.9   cp    0   0
#> 3   1    3  6.6   cp    0   0
#> 4   1    6 10.8   cp    0   0
#> 5   1   24  5.6   cp    0   0
#> 6   1   24 44.0  pca    0   0
#> 7   1   36  4.0   cp    0   0
#> 8   1   36 27.0  pca    0   0
#> 9   1   48  2.7   cp    0   0
#> 10  1   48 28.0  pca    0   0
#> 11  1   72  0.8   cp    0   0
#> 12  1   72 31.0  pca    0   0
#> 13  1  144 71.0  pca    0   0

posologyr can compute the EBE for the combined PKPD model with poso_estim_map()

map_warf_01  <- poso_estim_map(warf_01,mod_warfarin_nlmixr)
#> using C compiler: ‘gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’
map_warf_01
#> $eta
#>       ETA_ktr        ETA_ka        ETA_cl         ETA_v      ETA_emax 
#> -0.0004293951 -0.0004357456 -0.0003701722  0.0001061682 -0.0007027385 
#>      ETA_ec50      ETA_kout        ETA_e0 
#> -0.0000199625  0.9407374740 -0.8904010311 
#> 
#> $model
#> ── Solved rxode2 object ──
#> ── Parameters ($params): ──
#>     THETA_ktr      THETA_ka      THETA_cl       THETA_v    THETA_emax 
#>  0.1060000000 -0.0870000000 -2.0300000000  2.0700000000  3.4000000000 
#>    THETA_ec50    THETA_kout      THETA_e0         cp.sd    cp.prop.sd 
#>  0.0072400000 -2.9000000000  4.5700000000  0.1440000000  0.1500000000 
#>        pca.sd       ETA_ktr        ETA_ka        ETA_cl         ETA_v 
#>  3.9100000000 -0.0004293951 -0.0004357456 -0.0003701722  0.0001061682 
#>      ETA_emax      ETA_ec50      ETA_kout        ETA_e0 
#> -0.0007027385 -0.0000199625  0.9407374740 -0.8904010311 
#> ── Initial Conditions ($inits): ──
#>  depot    gut center effect 
#>      0      0      0      0 
#> ── First part of data (object): ──
#> # A tibble: 1,451 × 18
#>    time   ktr    ka    cl     v  emax  ec50  kout    e0   DCP    PD   kin    cp
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1   0    1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> 2   0.1  1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> 3   0.2  1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> 4   0.3  1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> 5   0.4  1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> 6   0.5  1.11 0.916 0.131  7.93 0.968  1.01 0.141  39.6     0     1  5.59     0
#> # ℹ 1,445 more rows
#> # ℹ 5 more variables: pca <dbl>, depot <dbl>, gut <dbl>, center <dbl>,
#> #   effect <dbl>
#> 
#> $event
#>          id  time   amt  evid
#>       <int> <num> <num> <int>
#>    1:     1   0.0    NA     0
#>    2:     1   0.0   100     1
#>    3:     1   0.1    NA     0
#>    4:     1   0.2    NA     0
#>    5:     1   0.3    NA     0
#>   ---                        
#> 1448:     1 144.6    NA     0
#> 1449:     1 144.7    NA     0
#> 1450:     1 144.8    NA     0
#> 1451:     1 144.9    NA     0
#> 1452:     1 145.0    NA     0

The observation/time curves for both endpoints can also be plotted

plot(map_warf_01$model,"cp")

Plot of the individual PK profile of warfarin

plot(map_warf_01$model,"pca")

Plot of the individual PD profile of warfarin