0 Prerequisites - packages

The list of R packages should be installed first to do the following testing.

# pkgs <- c("httk", "tidyverse", "sensitivity", "devtools")
# install.packages(pkgs)
# devtools::install_github("nanhung/pksensi")
library(httk)
library(tidyverse)
library(sensitivity)
library(pksensi)

Check the software package version that will be used in this example.

devtools::session_info()
## ─ Session info ──────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 3.6.0 (2019-04-26)
##  os       Ubuntu 18.04.2 LTS          
##  system   x86_64, linux-gnu           
##  ui       X11                         
##  language en_US                       
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       America/Chicago             
##  date     2019-05-29                  
## 
## ─ Packages ──────────────────────────────────────────────────────────────
##  package     * version date       lib source                          
##  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.6.0)                  
##  backports     1.1.4   2019-04-10 [1] CRAN (R 3.6.0)                  
##  boot          1.3-20  2017-07-30 [4] CRAN (R 3.5.0)                  
##  broom         0.5.2   2019-04-07 [1] CRAN (R 3.6.0)                  
##  callr         3.2.0   2019-03-15 [1] CRAN (R 3.6.0)                  
##  cellranger    1.1.0   2016-07-27 [1] CRAN (R 3.6.0)                  
##  cli           1.1.0   2019-03-19 [1] CRAN (R 3.6.0)                  
##  colorspace    1.4-1   2019-03-18 [1] CRAN (R 3.6.0)                  
##  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.6.0)                  
##  data.table    1.12.2  2019-04-07 [1] CRAN (R 3.6.0)                  
##  DBI           1.0.0   2018-05-02 [1] CRAN (R 3.6.0)                  
##  desc          1.2.0   2018-05-01 [1] CRAN (R 3.6.0)                  
##  deSolve       1.21    2018-05-09 [1] CRAN (R 3.6.0)                  
##  devtools      2.0.2   2019-04-08 [1] CRAN (R 3.6.0)                  
##  digest        0.6.19  2019-05-20 [1] CRAN (R 3.6.0)                  
##  dplyr       * 0.8.1   2019-05-14 [1] CRAN (R 3.6.0)                  
##  evaluate      0.13    2019-02-12 [1] CRAN (R 3.6.0)                  
##  expm          0.999-4 2019-03-21 [1] CRAN (R 3.6.0)                  
##  forcats     * 0.4.0   2019-02-17 [1] CRAN (R 3.6.0)                  
##  fs            1.2.7   2019-03-19 [1] CRAN (R 3.6.0)                  
##  generics      0.0.2   2018-11-29 [1] CRAN (R 3.6.0)                  
##  getPass       0.2-2   2017-07-21 [1] CRAN (R 3.6.0)                  
##  ggplot2     * 3.1.1   2019-04-07 [1] CRAN (R 3.6.0)                  
##  glue          1.3.1   2019-03-12 [1] CRAN (R 3.6.0)                  
##  gtable        0.3.0   2019-03-25 [1] CRAN (R 3.6.0)                  
##  haven         2.1.0   2019-02-19 [1] CRAN (R 3.6.0)                  
##  hms           0.4.2   2018-03-10 [1] CRAN (R 3.6.0)                  
##  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.6.0)                  
##  httk        * 1.9.2   2019-04-25 [1] CRAN (R 3.6.0)                  
##  httr          1.4.0   2018-12-11 [1] CRAN (R 3.6.0)                  
##  jsonlite      1.6     2018-12-07 [1] CRAN (R 3.6.0)                  
##  knitr         1.22    2019-03-08 [1] CRAN (R 3.6.0)                  
##  lattice       0.20-38 2018-11-04 [1] CRAN (R 3.6.0)                  
##  lazyeval      0.2.2   2019-03-15 [1] CRAN (R 3.6.0)                  
##  lubridate     1.7.4   2018-04-11 [1] CRAN (R 3.6.0)                  
##  magrittr      1.5     2014-11-22 [1] CRAN (R 3.6.0)                  
##  Matrix        1.2-17  2019-03-22 [4] CRAN (R 3.5.3)                  
##  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.6.0)                  
##  mitools       2.4     2019-04-26 [1] CRAN (R 3.6.0)                  
##  modelr        0.1.4   2019-02-18 [1] CRAN (R 3.6.0)                  
##  msm           1.6.7   2019-03-18 [1] CRAN (R 3.6.0)                  
##  munsell       0.5.0   2018-06-12 [1] CRAN (R 3.6.0)                  
##  mvtnorm       1.0-10  2019-03-05 [1] CRAN (R 3.6.0)                  
##  nlme          3.1-140 2019-05-12 [4] CRAN (R 3.6.0)                  
##  pillar        1.4.0   2019-05-11 [1] CRAN (R 3.6.0)                  
##  pkgbuild      1.0.3   2019-03-20 [1] CRAN (R 3.6.0)                  
##  pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.6.0)                  
##  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.6.0)                  
##  pksensi     * 1.1.1   2019-05-24 [1] Github (nanhung/pksensi@a728559)
##  plyr          1.8.4   2016-06-08 [1] CRAN (R 3.6.0)                  
##  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.6.0)                  
##  processx      3.3.0   2019-03-10 [1] CRAN (R 3.6.0)                  
##  ps            1.3.0   2018-12-21 [1] CRAN (R 3.6.0)                  
##  purrr       * 0.3.2   2019-03-15 [1] CRAN (R 3.6.0)                  
##  R6            2.4.0   2019-02-14 [1] CRAN (R 3.6.0)                  
##  Rcpp          1.0.1   2019-03-17 [1] CRAN (R 3.6.0)                  
##  readr       * 1.3.1   2018-12-21 [1] CRAN (R 3.6.0)                  
##  readxl        1.3.1   2019-03-13 [1] CRAN (R 3.6.0)                  
##  remotes       2.0.4   2019-04-10 [1] CRAN (R 3.6.0)                  
##  reshape       0.8.8   2018-10-23 [1] CRAN (R 3.6.0)                  
##  rlang         0.3.4   2019-04-07 [1] CRAN (R 3.6.0)                  
##  rmarkdown     1.12    2019-03-14 [1] CRAN (R 3.6.0)                  
##  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.6.0)                  
##  rstudioapi    0.10    2019-03-19 [1] CRAN (R 3.6.0)                  
##  rvest         0.3.3   2019-04-11 [1] CRAN (R 3.6.0)                  
##  scales        1.0.0   2018-08-09 [1] CRAN (R 3.6.0)                  
##  sensitivity * 1.15.2  2018-09-02 [1] CRAN (R 3.6.0)                  
##  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.6.0)                  
##  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.6.0)                  
##  stringr     * 1.4.0   2019-02-10 [1] CRAN (R 3.6.0)                  
##  survey        3.36    2019-04-27 [1] CRAN (R 3.6.0)                  
##  survival      2.43-3  2018-11-26 [4] CRAN (R 3.5.1)                  
##  testthat      2.1.1   2019-04-23 [1] CRAN (R 3.6.0)                  
##  tibble      * 2.1.1   2019-03-16 [1] CRAN (R 3.6.0)                  
##  tidyr       * 0.8.3   2019-03-01 [1] CRAN (R 3.6.0)                  
##  tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.6.0)                  
##  tidyverse   * 1.2.1   2017-11-14 [1] CRAN (R 3.6.0)                  
##  truncnorm     1.0-8   2018-02-27 [1] CRAN (R 3.6.0)                  
##  usethis       1.5.0   2019-04-07 [1] CRAN (R 3.6.0)                  
##  withr         2.1.2   2018-03-15 [1] CRAN (R 3.6.0)                  
##  xfun          0.6     2019-04-02 [1] CRAN (R 3.6.0)                  
##  xml2          1.2.0   2018-01-24 [1] CRAN (R 3.6.0)                  
##  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.6.0)                  
## 
## [1] /home/nanhung/R/x86_64-pc-linux-gnu-library/3.6
## [2] /usr/local/lib/R/site-library
## [3] /usr/lib/R/site-library
## [4] /usr/lib/R/library
mcsim_version()  
## The current GNU MCSim version is 6.1.0

MonteCarlo()

Use one_mtc.in.R to conduct Monte Carlo analysis

Modeling

#
out_mc <- mcsim(model = "one.model.R", input = "one_mtc.in.R") 
## * Created executable program 'mcsim.one.model.R.exe'.
## Execute: ./mcsim.one.model.R.exe modeling/one_mtc.in.R
out_mc
##    Iter       Ka        Ke C_central_1.1 C_central_1.2 C_central_1.3
## 1     0 0.758388 0.0573933             0      1029.520      1454.350
## 2     1 0.271753 0.0946798             0       453.108       757.464
## 3     2 0.568836 0.0804630             0       830.484      1236.480
## 4     3 0.305922 0.0327608             0       518.138       883.019
## 5     4 0.719031 0.0937336             0       973.510      1360.720
## 6     5 0.458833 0.0549646             0       714.600      1128.020
## 7     6 0.798923 0.0875557             0      1047.510      1430.870
## 8     7 0.276393 0.0917466             0       460.503       769.432
## 9     8 0.421889 0.0637113             0       665.427      1060.750
## 10    9 0.250307 0.0435725             0       432.974       751.610
##    C_central_1.4 C_central_1.5 C_central_1.6 C_central_1.7 C_central_1.8
## 1       1599.130       1615.74       1575.18       1510.54       1437.16
## 2        952.161       1066.66       1123.10       1138.08       1124.01
## 3       1407.110       1449.06       1422.38       1360.73       1282.88
## 4       1135.570       1305.92       1416.24       1482.84       1517.70
## 5       1470.060       1451.13       1376.15       1279.75       1178.27
## 6       1353.140       1461.18       1497.06       1489.06       1454.97
## 7       1522.870       1490.54       1408.48       1309.68       1208.57
## 8        966.930       1083.13       1140.62       1156.25       1142.61
## 9       1281.460       1390.05       1427.34       1419.97       1385.26
## 10       982.014       1144.48       1254.77       1325.13       1365.06
##    C_central_1.9
## 1        1362.10
## 2        1090.09
## 3        1199.17
## 4        1529.66
## 5        1079.18
## 6        1405.95
## 7        1111.15
## 8        1108.96
## 9        1334.47
## 10       1381.93
out_mc
##    Iter       Ka        Ke C_central_1.1 C_central_1.2 C_central_1.3
## 1     0 0.758388 0.0573933             0      1029.520      1454.350
## 2     1 0.271753 0.0946798             0       453.108       757.464
## 3     2 0.568836 0.0804630             0       830.484      1236.480
## 4     3 0.305922 0.0327608             0       518.138       883.019
## 5     4 0.719031 0.0937336             0       973.510      1360.720
## 6     5 0.458833 0.0549646             0       714.600      1128.020
## 7     6 0.798923 0.0875557             0      1047.510      1430.870
## 8     7 0.276393 0.0917466             0       460.503       769.432
## 9     8 0.421889 0.0637113             0       665.427      1060.750
## 10    9 0.250307 0.0435725             0       432.974       751.610
##    C_central_1.4 C_central_1.5 C_central_1.6 C_central_1.7 C_central_1.8
## 1       1599.130       1615.74       1575.18       1510.54       1437.16
## 2        952.161       1066.66       1123.10       1138.08       1124.01
## 3       1407.110       1449.06       1422.38       1360.73       1282.88
## 4       1135.570       1305.92       1416.24       1482.84       1517.70
## 5       1470.060       1451.13       1376.15       1279.75       1178.27
## 6       1353.140       1461.18       1497.06       1489.06       1454.97
## 7       1522.870       1490.54       1408.48       1309.68       1208.57
## 8        966.930       1083.13       1140.62       1156.25       1142.61
## 9       1281.460       1390.05       1427.34       1419.97       1385.26
## 10       982.014       1144.48       1254.77       1325.13       1365.06
##    C_central_1.9
## 1        1362.10
## 2        1090.09
## 3        1199.17
## 4        1529.66
## 5        1079.18
## 6        1405.95
## 7        1111.15
## 8        1108.96
## 9        1334.47
## 10       1381.93

SetPoints()

Use one_setpts.in.Rto conduct setpoint analysis

Modeling

#
out_sp <- mcsim("one.model.R", "one_setpts.in.R")
## Execute: ./mcsim.one.model.R.exe modeling/one_setpts.in.R
out_sp
##    Iter       Ka        Ke C_central_1.1 C_central_1.2 C_central_1.3
## 1     0 0.758388 0.0573933             0      1029.520      1454.350
## 2     1 0.271753 0.0946798             0       453.108       757.464
## 3     2 0.568836 0.0804630             0       830.484      1236.480
## 4     3 0.305922 0.0327608             0       518.138       883.019
## 5     4 0.719031 0.0937336             0       973.510      1360.720
## 6     5 0.458833 0.0549646             0       714.600      1128.020
## 7     6 0.798923 0.0875557             0      1047.510      1430.870
## 8     7 0.276393 0.0917466             0       460.503       769.432
## 9     8 0.421889 0.0637113             0       665.427      1060.750
## 10    9 0.250307 0.0435725             0       432.974       751.610
##    C_central_1.4 C_central_1.5 C_central_1.6 C_central_1.7 C_central_1.8
## 1       1599.130       1615.74       1575.18       1510.54       1437.16
## 2        952.161       1066.66       1123.10       1138.08       1124.01
## 3       1407.110       1449.06       1422.38       1360.73       1282.88
## 4       1135.570       1305.92       1416.24       1482.84       1517.70
## 5       1470.060       1451.13       1376.15       1279.75       1178.27
## 6       1353.140       1461.18       1497.06       1489.06       1454.97
## 7       1522.870       1490.54       1408.48       1309.68       1208.57
## 8        966.930       1083.13       1140.62       1156.25       1142.61
## 9       1281.460       1390.05       1427.34       1419.97       1385.26
## 10       982.014       1144.48       1254.77       1325.13       1365.06
##    C_central_1.9
## 1        1362.10
## 2        1090.09
## 3        1199.17
## 4        1529.66
## 5        1079.18
## 6        1405.95
## 7        1111.15
## 8        1108.96
## 9        1334.47
## 10       1381.93

1 Example 1: 1-compartment model

In this section, we’ll use 1-compartment model in httk package as the example to conduct uncertainty and sensitivity analysis.

The parameterize_1comp() provide the baseline value of parameters that needed in the 1-compartment model. The selected chemical in this case study is Bisphenol A.

params <- parameterize_1comp(chem.name = "Bisphenol A")
params
## $Vdist
## [1] 6.137241
## 
## $kelim
## [1] 0.02283233
## 
## $Clint
## [1] 19.29
## 
## $Funbound.plasma
## [1] 0.03224888
## 
## $Funbound.plasma.adjustment
## [1] 0.4742482
## 
## $Fhep.assay.correction
## [1] 0.6652326
## 
## $Pow
## [1] 2242.591
## 
## $pKa_Donor
## [1]  9.78 10.39
## 
## $pKa_Accept
## [1] NA
## 
## $MA
## [1] 28840.32
## 
## $kgutabs
## [1] 2.18
## 
## $Rblood2plasma
## [1] 0.79
## 
## $million.cells.per.gliver
## [1] 110
## 
## $liver.density
## [1] 1.05
## 
## $hematocrit
## [1] 0.44
## 
## $MW
## [1] 228.291
## 
## $Fgutabs
## [1] 1
## 
## $hepatic.bioavailability
## [1] 0.860811
## 
## $BW
## [1] 70

Select the parameters of molecular weight (MW), absorption fraction (Fgutabs), distribution volume (Vdist), absorption rate (kgutabs), and elimination rate (kelim) that will be used in uncertainty and sensitivity analysis.

MW <- params$MW
Fgutabs <- params$Fgutabs * params$hepatic.bioavailability
kgutabs <- params$kgutabs
Vdist <- params$Vdist
kelim <- params$kelim

1.1 Forward simulation

Use solve1comp to simulate the time-dependent concentration of BPA. The given daily dose is 1 mg/kg.

# Time
t <- seq(0, 20 ,0.1)
# solve_1comp
out <- solve_1comp(chem.name = "Bisphenol A", doses.per.day = 1, daily.dose = 1, times = t)
## Human amounts returned in umol and concentration returned in uM units.
## AUC is area under plasma concentration curve in uM * days units with Rblood2plasma = 0.79 .
data <- as.data.frame(out)

Plot the TK profile and add the mean css from calc_analytic_css() in httk and the maximum css through analytical solution. The equation of Css is

\[Css=\frac{D \cdot Fgutabs}{kelim \cdot Vdist}\]

# Estimate css
dose <- 1 / 1000 * MW # mg -> uM
httk_css <- calc_analytic_css(chem.name = "Bisphenol A", model = "1compartment")
## Warning in predict_partitioning_schmitt(parameters = outlist):
## Humanfractional tissue volumes used in calculation. Parameters should match
## species argument used (Human).
## Warning in available_rblood2plasma(chem.cas = chem.cas, chem.name =
## chem.name, : Human in vivo Rblood2plasma returned.
## Human plasma concentration returned in uM units.
sol_css <-  dose * Fgutabs / kelim / Vdist # Analytical solution of css

# Plot result
plot(data$time, data$Ccompartment, type = "l", main = "BPA (pbtk1cpt)",
     xlab = "Time (day)", ylab = "Concentration (uM)")
abline(h = sol_css, col = "red") # Maximum  
abline(h = httk_css) # Mean

Use GNU MCSim’s model (“pbtk1cpt.model.R”) and input (“pbtk1cpt.in.R”) files to solve the ODE and compare with httk’s result.

out_mcsim <- mcsim(model = "pbtk1cpt.model.R", input = "pbtk1cpt.in.R", dir = "modeling/pbtk1cpt")
## * Created executable program 'mcsim.pbtk1cpt.model.R.exe'.
## Execute: ./mcsim.pbtk1cpt.model.R.exe modeling/pbtk1cpt/pbtk1cpt.in.R

Plot result

plot(out_mcsim$Time, out_mcsim$Ccompartment, type = "l", main = "BPA",
     xlab = "Time (hr)", ylab = "Concentration (uM)")

# Add line 
lines(data$time * 24, data$Ccompartment, col = "red")

1.2 Uncertainty analysis of Css

Consider the CV = 0.2 as uncertainty in volume of distribution and elimination rate constant. The range of absorption fraction in gut is setting at 0.8 to 1.0.

R

Use R function to generate the random sample based on the given sampling method. We assume the normal distribution for Vdist and kelim, and uniform distribution for gutabs.

Vdist_dist <- rnorm(n = 1000, mean = Vdist, sd = Vdist * 0.2) # CV = 0.2
kelim_dist <- rnorm(n = 1000, mean = kelim, sd = kelim * 0.2) # CV = 0.2
Fgutabs_dist <- runif(n = 1000, min = 0.8, max = 1.0)
css_dist <- dose * Fgutabs_dist / kelim_dist / Vdist_dist 
summary(css_dist)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.716   1.249   1.503   1.622   1.851   6.250

Visualize the parameter distribution through histogram.

par(mfrow = c(2,2))
hist(Vdist_dist)
hist(kelim_dist)
hist(Fgutabs_dist)
hist(css_dist)

MCSim

Run MC simulation by using model (“pbtk1cpt_css.model.R”) and input (“pbtk1cpt_css_mtc.in.R”) files.

out <- mcsim(model = "pbtk1cpt_css.model.R", input = "pbtk1cpt_css_mtc.in.R", dir = "modeling/pbtk1cpt")
## * Created executable program 'mcsim.pbtk1cpt_css.model.R.exe'.
## Execute: ./mcsim.pbtk1cpt_css.model.R.exe modeling/pbtk1cpt/pbtk1cpt_css_mtc.in.R
head(out)
##   Iter  Fgutabs     kelim   Vdist css_1.1
## 1    0 0.998091 0.0311610 7.01874 1.04181
## 2    1 0.940106 0.0327880 4.98724 1.31247
## 3    2 0.949883 0.0284472 3.82896 1.99085
## 4    3 0.848450 0.0229008 1.81946 4.64861
## 5    4 0.824792 0.0283581 5.67027 1.17099
## 6    5 0.823751 0.0230576 7.01450 1.16272
summary(out$css_1.1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.7362  1.2525  1.5012  1.6189  1.8686  4.6486

Visualize the parameter distribution through histogram.

par(mfrow = c(2,2))
hist(out$Vdist)
hist(out$kelim)
hist(out$Fgutabs)
hist(out$css_1.1)

Compare the results from R and MCSim

# The example of using pipeline
# plot(density(css_dist))
css_dist %>% density() %>% plot()
out$css_1.1 %>% density() %>% lines(col = "red")

1.3 Uncertainty analysis of RTK modeling

The statistic data is from He et al. (2009) reported that the background bisphenol A (BPA) levels in serum of a Chinese population without occupational exposure. Of the total of 952 subjects, the serum BPA levels was 2.84 μg/L (arithmetic mean) and 0.18 μg/L (geometric mean). The detectable rate was 17% with the detection limit of 0.39 μg/L.

R

Generate the lognormal distribution of Css

Css <- rlnorm(n = 1000, meanlog = log(0.18/1000), sdlog = log(7)) # μg/L to mg/l
exp(sd(log(Css))) # Geometric Standard deviation
## [1] 7.229771
oral_equiv_dist <- Css * kelim_dist * Vdist_dist / Fgutabs_dist # mg/kg-d
summary(oral_equiv_dist)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 7.100e-08 7.085e-06 2.770e-05 1.914e-04 1.031e-04 1.441e-02

Make a histogram for oral equivalent distribution.

hist(oral_equiv_dist, main = "Predicted oral equivalent dose (mg/kg-d)")

Make a box plot

boxplot(oral_equiv_dist, log = "y", main = "Predicted oral equivalent dose (mg/kg-d)")

Plot the relationship between Css and oral equivalent dose. The detection rate and arithmetic mean are used to compare with “real” study data.

plot(Css, oral_equiv_dist, log = "xy", xlab = "Css (uM)", ylab = "oral equivalent dose (mg/kg-d)")
abline(v = 0.31/1000) # Add line of "real" detection limit

x <- subset(Css, Css > 0.31/1000)
length(x)/1000 # detection rate
## [1] 0.402
mean(x) * 1000 # arithmetic mean
## [1] 2.955248

MCSim

In this part, we will apply the same approach through MCSim. First, use mcsim() for the model (“pbtk1cpt_rtk.model.R”) and input (“pbtk1cpt_rtk.in.R”) files. Use set.seed() to create reproducible result

set.seed(1234)
out <- mcsim(model = "pbtk1cpt_rtk.model.R", input = "pbtk1cpt_rtk.in.R", dir = "modeling/pbtk1cpt")
## * Created executable program 'mcsim.pbtk1cpt_rtk.model.R.exe'.
## Execute: ./mcsim.pbtk1cpt_rtk.model.R.exe modeling/pbtk1cpt/pbtk1cpt_rtk.in.R
summary(out$Dose_1.1)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 1.200e-08 6.057e-06 2.323e-05 1.950e-04 8.852e-05 1.857e-02

Then, make histograms of Css and oral equivalent does

par(mfrow = c(1,2))
hist(out$Css)
hist(out$Dose_1.1)

Plot the relationship between Css and oral equivalent dose. The detection rate and arithmetic mean are used to compare with “real” study data.

plot(out$Css, out$Dose_1.1, log = "xy", xlab = "Css (uM)", ylab = "oral equivalent dose (mg/kg-d)")
abline(v = 0.31/1000) # detection limit
x <- subset(out$Css, out$Css > 0.31/1000)
DR_13 <- quantile(x, prob = 0.13)
DR_13 * 1000 # ug/L
##       13% 
## 0.4012078
abline(v = DR_13, col = "red") # 13 % Detection rate

length(x)/1000 # Detection rate
## [1] 0.359
mean(x) * 1000 # arithmetic mean
## [1] 3.323244

Compare the simulations from R and MCSim

boxplot(out$Dose_1.1, oral_equiv_dist, log = "y", names = c("R","MCSim"))

The variation of 10 different simulations

for (i in 1:10)
{
  out <- mcsim("pbtk1cpt_rtk.model.R", "pbtk1cpt_rtk.in.R", dir = "modeling/pbtk1cpt")
  x <- subset(out$Css, out$Css > 0.31/1000)
  Detect.rate <- length(x)/1000 # Detection rate
  Observ.mean <- mean(x) * 1000 # arithmetic mean
  plot(out$Css, out$Dose_1.1, log = "xy", 
       xlab = "Css (uM)", ylab = "oral equivalent dose (mg/kg-d)",
       main = paste("Detection rate: ", round(Detect.rate, digit = 2), 
                    "Observation mean: ", round(Observ.mean, digit = 2)))
  abline(v = 0.31/1000) # detection limit
  DL <- quantile(x, prob = 0.13)
  abline(v = DL, col = "red") # 13 %
  date_time<-Sys.time()
  while((as.numeric(Sys.time()) - as.numeric(date_time))<1){} 
}

1.4 Sensitivity analysis

Here we use two simple examples to explain the concept of sensitivity analysis for Morris’s elementary effects screening method and Fourier amplitude sensitivity testing (FAST). The equations are defined as follows

\[Y=X_{1}+X_{2}+X_{3}\]

\[Y=X_{1} \cdot X_{2}/X_{3}\]

where \(X_i\) are uniformly distributed as follows

\[X_1 \sim N(0,1)\] \[X_2 \sim N(1,4)\] \[X_3 \sim N(1,7)\]

The defined functions are called eqn_1() and eqn_2()

eqn_1 <- function (X)
{
  X[, 1] + X[, 2] + X[, 3] # X1 + X2 + X3
}
eqn_2 <- function (X) 
{
  X[, 1] * X[, 2] / X[, 3] # X1 * X2 / X3
}

Morris method for eqn_1()

The Morris method,based on design of experiments, allows to identify the few important factors at a cost of \(r(p+ 1)\) simulations (where \(p\) is the number of factors). \(r\) is the number of repetitions of the design.

Using morris() and setting the arguments. The distribution for X1, X2, and X3 are U(0,1), U(1,4), and U(1,7), respectively.

set.seed(1234)
x <- morris(model = eqn_1, factors = 3, r = 18, 
            design = list(type = "oat", levels = 6, grid.jump = 3), 
            binf = c(0, 1, 1), bsup = c(1, 4, 7))
nrow(x$X) # Model evaluation
## [1] 72
#head(x$X)

Plotting sampling process

par(mfrow = c(3,1), mar = c(2,4,1,1))
plot(x$X[, 1], xlab = "n", ylab = "x1")
plot(x$X[, 2], ylab = "x2")
plot(x$X[, 3], ylab = "x3")

Parameter distributions

par(mfrow = c(1,3))
for(i in 1:3){
  hist(x$X[,i], main = colnames(x$X)[i])
}

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

The \(\mu^*\) is the mean absolute value of elementary effect, representing the actual value from the output that was effected by specific parameter. The \(\sigma\) is the standard deviation of elementary effect, which can also represent the interaction of the parameters.

plot(x)

Report

x
## 
## Call:
## morris(model = eqn_1, factors = 3, r = 18, design = list(type = "oat",     levels = 6, grid.jump = 3), binf = c(0, 1, 1), bsup = c(1,     4, 7))
## 
## Model runs: 72 
##    mu mu.star        sigma
## X1  1       1 1.355467e-15
## X2  3       3 9.871551e-16
## X3  6       6 1.160045e-15

Analytical solution (first order)

1-0 # X1
## [1] 1
4-1 # X2
## [1] 3
7-1 # X3
## [1] 6

FAST for eqn_1()

Using fast99() and setting the arguments. This method allows the estimation of first order and total Sobol indices for all the factors (alltogether \(2p\) indices, where \(p\) is the number of factors) at a total cost of \(n \times p\) simulations.

Set parameter distribution

q <- "qunif"
q.arg <- list(list(min = 0,  max = 1),
              list(min = 1,  max = 4),
              list(min = 1,  max = 7))

Using fast99() and setting the arguments

x <- fast99(model = eqn_1, factors = 3, n = 128, # Need n = 1000 to converge 
            q = q, q.arg = q.arg)

Plotting sampling process

par(mfrow = c(3,1), mar = c(2,2,1,1))
plot(x$X[,1], type = "l")
plot(x$X[,2], type = "l")
plot(x$X[,3], type = "l")

Parameter distributions

par(mfrow = c(1,3))
for(i in 1:3){
  hist(x$X[,i], main = colnames(x$X)[i])
}

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

Plot the sensitivity measurements

plot(x)

Report

x
## 
## Call:
## fast99(model = eqn_1, factors = 3, n = 128, q = q, q.arg = q.arg)
## 
## Model runs: 384 
## 
## Estimations of the indices:
##    first order total order
## X1  0.01118566   0.0114904
## X2  0.15241837   0.1529183
## X3  0.69199565   0.6934759

Analytical solution

Total <- (1-0)^2 + (4-1)^2 + (7-1)^2
1^2 / Total # S1
## [1] 0.02173913
3^2 / Total # S2
## [1] 0.1956522
6^2 / Total # S3
## [1] 0.7826087

Morris method for eqn_2()

Call morris() and use the same parameter setting as previous case.

set.seed(1234)
x <- morris(model = eqn_2, factors = 3, r = 18, 
            design = list(type = "oat", levels = 6, grid.jump = 3),
            binf = c(0,1,1), bsup = c(1,4,7))
nrow(x$X) # Model evaluation
## [1] 72

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

Plot the sensitivity measurements

plot(x, xlim = c(0,2), ylim = c(0,2))

Report

x
## 
## Call:
## morris(model = eqn_2, factors = 3, r = 18, design = list(type = "oat",     levels = 6, grid.jump = 3), binf = c(0, 1, 1), bsup = c(1,     4, 7))
## 
## Model runs: 72 
##            mu   mu.star     sigma
## X1  1.0008280 1.0008280 0.8454144
## X2  0.5051922 0.5051922 0.7424151
## X3 -0.8651525 0.8651525 1.2190095

FAST method for eqn_2()

q <- "qunif"
q.arg <- list(list(min = 0,  max = 1),
              list(min = 1,  max = 4),
              list(min = 1,  max = 7))

Call fast99()

x <- fast99(model = eqn_2, factors = 3, n = 1000, q = q, q.arg = q.arg) #

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

Plot the sensitivity measurements

plot(x)

Report

x
## 
## Call:
## fast99(model = eqn_2, factors = 3, n = 1000, q = q, q.arg = q.arg)
## 
## Model runs: 3000 
## 
## Estimations of the indices:
##    first order total order
## X1   0.3220563   0.5063070
## X2   0.1160247   0.2293264
## X3   0.3396511   0.5139026

Morris method of Css

Define the function to estimate the maximum concentration at steady-state (Css)

Css_fun <- function (X) 
{
  Dose <- 0.228 # Ingestion dose (uM)
  Dose * X[, 1] / X[, 2] / X[, 3] # Fgutabs_dist / kelim_dist / Vdist_dist 
}

Set parameter range,

# The order of binf and bsup are c(Fgutabs, kelim, Vdist)
binf <- c(0.8, kelim * 0.5, Vdist * 0.5)
bsup <- c(1, kelim * 2, Vdist * 2)

Call morris()

set.seed(1234)
x <- morris(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"), r = 32, 
            design = list(type = "oat", levels = 6, grid.jump = 3), 
            binf = binf, bsup = bsup)

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

Plot the sensitivity measurements

par(mfrow = c(1,1))
plot(x, xlim = c(0, 5), ylim = c(0, 5))
abline(0,1) # non-linear and/or non-monotonic
abline(0,0.5, lty = 2) # monotonic
abline(0,0.1, lty = 3) # almost linear
legend("topleft", legend = c("non-linear and/or non-monotonic",
                             "monotonic", "linear"), lty = c(1:3))

The stability testing

for (i in 1:10)
{
  x <- morris(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"), r = 32, # test r = 32
              design = list(type = "oat", levels = 6, grid.jump = 3), 
              binf = binf, bsup = bsup)
  plot(x, xlim = c(0, 6), ylim = c(0, 6))
  abline(0,1) # non-linear and/or non-monotonic
  abline(0,0.5, lty = 2) # monotonic
  abline(0,0.1, lty = 3) # almost linear
  legend("topleft", legend = c("non-linear and/or non-monotonic",
                               "monotonic", "linear"), lty = c(1:3))
  date_time<-Sys.time()
  while((as.numeric(Sys.time()) - as.numeric(date_time))<1){} 
}

The example of convergence diagnostics

for (i in 3:11){
  x <- morris(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"), r = 2^i, # test r = 32
              design = list(type = "oat", levels = 6, grid.jump = 3), 
              binf = binf, bsup = bsup)
  if (i == 3){ X <- apply(abs(x$ee), 2, mean) } else X <- rbind(X, apply(abs(x$ee), 2, mean))
}
X
##     Fgutabs     kelim    Vdist
## X 0.2240959 1.1615334 1.143272
##   0.2137596 0.9145757 1.374492
##   0.3056444 2.0466927 2.010046
##   0.3404735 1.8931413 1.970940
##   0.3028373 1.9423194 1.924475
##   0.3253824 1.9860593 1.988660
##   0.3041595 1.8543542 1.867326
##   0.3212376 1.8882862 1.942005
##   0.3243742 1.9074727 1.896238
ylim <- range(X)
plot(X[,1], ylim = ylim, type = "b", xaxt = "n")
axis(1, at = seq(1,9,1), labels = 2^seq(3,11,1))
lines(X[,2], type = "b")
lines(X[,3], type = "b")

FAST method of Css

Set parameter distribution

q <- "qunif"
q.arg <- list(list(min = 0.8,  max = 1.0),
              list(min = kelim * 0.5,  max = kelim * 2),
              list(min = Vdist * 0.5,  max = Vdist * 2))

Call fast99()

x <- fast99(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"), 
            n = 500, q = q, q.arg = q.arg)

Visualize the relationship between parameters and model outputs

par(mfrow = c(1,3))
for(i in 1:3){
  cor <- cor(x$X[,i], x$y)
  plot(x$X[,i], x$y, 
       xlab = colnames(x$X)[i],
       main = paste("r = ", round(cor, digits = 2)))
}

Plot the sensitivity measurements

plot(x)

Report

x
## 
## Call:
## fast99(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"),     n = 500, q = q, q.arg = q.arg)
## 
## Model runs: 1500 
## 
## Estimations of the indices:
##         first order total order
## Fgutabs  0.01211322  0.02427179
## kelim    0.44375555  0.53829078
## Vdist    0.44375555  0.53829078

The example of convergence diagnostics

for (i in 1:8){
  x <- fast99(model = Css_fun, factors = c("Fgutabs", "kelim", "Vdist"), n = 2^(i+6),
            q = q, q.arg = q.arg)
  if (i == 1){ X <- 1 - x$Dt/x$V } else X <- rbind(X, 1 - x$Dt/x$V)
}
ylim <- range(X)
X
##         [,1]      [,2]      [,3]
## X 0.03065326 0.6140697 0.6140697
##   0.02860018 0.5356477 0.5356477
##   0.01497975 0.5571496 0.5571496
##   0.02325690 0.5420919 0.5420919
##   0.02366698 0.5397771 0.5397771
##   0.02330789 0.5394178 0.5394178
##   0.02348126 0.5394023 0.5394023
##   0.02352585 0.5393984 0.5393984
plot(X[,1], ylim = ylim, type = "b", xaxt = "n")
axis(1, at = seq(1,8,1), labels = 2^seq(7,14,1))
lines(X[,2], type = "b")
lines(X[,3], type = "b")

2 Mutivariate toxicokinetic modeling

Instead of exams the sensitivity of single variables, this test case will use multi time points in uncertainty and sensitivity analysis.

2.1 Uncertainty analysis

In uncertainty analysis, Use model (pbtk1cpt.model.R) and input (pbtk1cpt_mtc.in.R) files to conduct Monte Carlo simulation.

out <- mcsim("pbtk1cpt.model.R", "pbtk1cpt_mtc.in.R", dir = "modeling/pbtk1cpt")
## Execute: ./mcsim.pbtk1cpt.model.R.exe modeling/pbtk1cpt/pbtk1cpt_mtc.in.R
head(out)
##   Iter   Vdist     kelim kgutabs  Fgutabs Ccompartment_1.1
## 1    0 7.46256 0.0321011 2.41957 0.887711                0
## 2    1 5.74118 0.0192948 2.60194 0.812587                0
## 3    2 7.19721 0.0224967 2.32319 0.954795                0
## 4    3 5.81295 0.0216096 1.57485 0.907221                0
## 5    4 5.29526 0.0216881 2.35532 0.963012                0
## 6    5 6.06293 0.0261181 2.89930 0.838847                0
##   Ccompartment_1.2 Ccompartment_1.3 Ccompartment_1.4 Ccompartment_1.5
## 1         0.464413         0.491055         0.479217         0.464404
## 2         0.566375         0.597539         0.589231         0.578202
## 3         0.516254         0.555344         0.547944         0.536241
## 4         0.534826         0.634121         0.643492         0.634481
## 5         0.710507         0.762663         0.752697         0.737151
## 6         0.562121         0.578579         0.565367         0.550885
##   Ccompartment_1.6 Ccompartment_1.7 Ccompartment_1.8 Ccompartment_1.9
## 1         0.449762         0.435556         0.421796         0.408471
## 2         0.567170         0.556333         0.545701         0.535272
## 3         0.524359         0.512699         0.501294         0.490143
## 4         0.621901         0.608809         0.595836         0.583107
## 5         0.721395         0.705923         0.690778         0.675957
## 6         0.536689         0.522853         0.509374         0.496243
##   Ccompartment_1.10 Ccompartment_1.11 Ccompartment_1.12 Ccompartment_1.13
## 1          0.395567          0.383070          0.370969          0.359249
## 2          0.525043          0.515009          0.505167          0.495514
## 3          0.479239          0.468578          0.458154          0.447962
## 4          0.570644          0.558445          0.546507          0.534824
## 5          0.661455          0.647264          0.633377          0.619788
## 6          0.483450          0.470986          0.458844          0.447015
##   Ccompartment_1.14 Ccompartment_1.15 Ccompartment_1.16 Ccompartment_1.17
## 1          0.347900          0.336910          0.326266          0.315959
## 2          0.486045          0.476756          0.467646          0.458709
## 3          0.437997          0.428254          0.418727          0.409412
## 4          0.523390          0.512201          0.501252          0.490536
## 5          0.606491          0.593479          0.580746          0.568286
## 6          0.435491          0.424264          0.413327          0.402671
##   Ccompartment_1.18 Ccompartment_1.19 Ccompartment_1.20 Ccompartment_1.21
## 1          0.305977          0.296311          0.286950          0.277885
## 2          0.449943          0.441345          0.432911          0.424638
## 3          0.400305          0.391400          0.382693          0.374179
## 4          0.480049          0.469787          0.459744          0.449916
## 5          0.556094          0.544163          0.532488          0.521064
## 6          0.392290          0.382177          0.372325          0.362726
##   Ccompartment_1.22 Ccompartment_1.23 Ccompartment_1.24
## 1          0.269106          0.260605          0.252372
## 2          0.416523          0.408563          0.400756
## 3          0.365856          0.357717          0.349759
## 4          0.440298          0.430885          0.421674
## 5          0.509885          0.498945          0.488241
## 6          0.353375          0.344265          0.335390

The format of output file can not be used to create TK profile directly. Therefore, we need to manipulate the output result to “tidy data” format.

# Find location of the first and last time points by which()
index <- which(names(out)=="Ccompartment_1.1" | names(out)=="Ccompartment_1.24")
# Use apply() to find the quantile of each time point
X <- apply(out[,index[1]:index[2]], 2, quantile, c(0.5, 0.025,0.975))
dat <- t(X)
# Set column names
colnames(dat) <- c("median", "LCL", "UCL")
df <- as.data.frame(dat)
# Set corresponding time
df$time <- seq(0, 23, 1)
df
##                      median       LCL       UCL time
## Ccompartment_1.1  0.0000000 0.0000000 0.0000000    0
## Ccompartment_1.2  0.5538240 0.3727134 0.9373901    1
## Ccompartment_1.3  0.6066980 0.4183666 1.0095713    2
## Ccompartment_1.4  0.6037840 0.4162458 1.0071525    3
## Ccompartment_1.5  0.5919100 0.4088154 0.9872847    4
## Ccompartment_1.6  0.5783875 0.4001410 0.9673558    5
## Ccompartment_1.7  0.5645915 0.3906346 0.9475459    6
## Ccompartment_1.8  0.5525695 0.3806796 0.9274493    7
## Ccompartment_1.9  0.5402475 0.3712848 0.9090722    8
## Ccompartment_1.10 0.5289945 0.3615694 0.8904363    9
## Ccompartment_1.11 0.5178065 0.3538282 0.8739117   10
## Ccompartment_1.12 0.5061370 0.3447121 0.8567475   11
## Ccompartment_1.13 0.4947160 0.3339378 0.8417273   12
## Ccompartment_1.14 0.4828340 0.3242194 0.8214774   13
## Ccompartment_1.15 0.4714790 0.3176689 0.8080284   14
## Ccompartment_1.16 0.4605640 0.3109047 0.7891673   15
## Ccompartment_1.17 0.4507240 0.3012451 0.7710631   16
## Ccompartment_1.18 0.4407930 0.2914414 0.7561948   17
## Ccompartment_1.19 0.4317305 0.2823120 0.7391283   18
## Ccompartment_1.20 0.4210795 0.2764975 0.7257780   19
## Ccompartment_1.21 0.4117390 0.2685563 0.7088276   20
## Ccompartment_1.22 0.4030305 0.2614560 0.6987209   21
## Ccompartment_1.23 0.3940585 0.2536938 0.6889016   22
## Ccompartment_1.24 0.3863955 0.2475818 0.6792196   23

Visualize

ggplot(df, aes(x = time, y = median)) +
  geom_ribbon(aes(ymin = LCL, ymax = UCL), fill = "grey70", alpha = 0.5) + 
  geom_line() +
  labs(x = "Time (h)", y = "Concentration (uM)")

2.2 Sensitivity analysis

Setpoints method (Morris)

Call Morris()

# The order of binf and bsup are c("Vdist", "kelim", "kgutabs", "Fgutabs")
binf <- c(Vdist * 0.5, kelim * 0.5, kgutabs * 0.5, 0.8)
bsup <- c(Vdist * 2, kelim * 2, kgutabs * 2, 1.0)
set.seed(1234)
x <- morris(model = NULL, factors = c("Vdist", "kelim", "kgutabs", "Fgutabs"), r = 32, 
            design = list(type = "oat", levels = 6, grid.jump = 3), 
            binf = binf, bsup = bsup)
head(x$X)
##          Vdist      kelim kgutabs Fgutabs
## [1,]  4.909793 0.01826586   2.398    0.84
## [2,] 10.433310 0.01826586   2.398    0.84
## [3,] 10.433310 0.01826586   4.360    0.84
## [4,] 10.433310 0.01826586   4.360    0.96
## [5,] 10.433310 0.03881496   4.360    0.96
## [6,]  4.909793 0.01141616   4.360    0.88
nrow(x$X)
## [1] 160

Create the setpoints file setpts.out

X <- cbind(1, x$X)
write.table(X, file = "setpts.out", row.names = F, sep = "\t")

Modeling

out <- mcsim("pbtk1cpt.model.R", "pbtk1cpt_setpts.in.R", dir = "modeling/pbtk1cpt")
## Execute: ./mcsim.pbtk1cpt.model.R.exe modeling/pbtk1cpt/pbtk1cpt_setpts.in.R
head(out)
##   Iter    Vdist     kelim kgutabs Fgutabs Ccompartment_1.1
## 1    0  4.90979 0.0182659   2.398    0.84                0
## 2    1 10.43330 0.0182659   2.398    0.84                0
## 3    2 10.43330 0.0182659   4.360    0.84                0
## 4    3 10.43330 0.0182659   4.360    0.96                0
## 5    4 10.43330 0.0388150   4.360    0.96                0
## 6    5  4.90979 0.0114162   4.360    0.88                0
##   Ccompartment_1.2 Ccompartment_1.3 Ccompartment_1.4 Ccompartment_1.5
## 1         0.672862         0.721846         0.714340         0.701916
## 2         0.316641         0.339692         0.336160         0.330313
## 3         0.343218         0.341391         0.335268         0.329201
## 4         0.392249         0.390162         0.383164         0.376229
## 5         0.385993         0.376230         0.361969         0.348189
## 6         0.768177         0.769274         0.760667         0.752034
##   Ccompartment_1.6 Ccompartment_1.7 Ccompartment_1.8 Ccompartment_1.9
## 1         0.689257         0.676786         0.664536         0.652508
## 2         0.324356         0.318487         0.312723         0.307063
## 3         0.323242         0.317391         0.311647         0.306006
## 4         0.369419         0.362733         0.356167         0.349721
## 5         0.334933         0.322182         0.309916         0.298117
## 6         0.743497         0.735058         0.726714         0.718465
##   Ccompartment_1.10 Ccompartment_1.11 Ccompartment_1.12 Ccompartment_1.13
## 1          0.640698          0.629101          0.617714          0.606534
## 2          0.301505          0.296048          0.290689          0.285428
## 3          0.300467          0.295029          0.289688          0.284445
## 4          0.343391          0.337175          0.331073          0.325080
## 5          0.286767          0.275850          0.265348          0.255246
## 6          0.710309          0.702246          0.694275          0.686394
##   Ccompartment_1.14 Ccompartment_1.15 Ccompartment_1.16 Ccompartment_1.17
## 1          0.595555          0.584776          0.574191          0.563798
## 2          0.280261          0.275189          0.270208          0.265317
## 3          0.279297          0.274241          0.269278          0.264404
## 4          0.319196          0.313419          0.307746          0.302176
## 5          0.245528          0.236181          0.227189          0.218540
## 6          0.678603          0.670900          0.663284          0.655755
##   Ccompartment_1.18 Ccompartment_1.19 Ccompartment_1.20 Ccompartment_1.21
## 1          0.553594          0.543574          0.533735          0.524074
## 2          0.260515          0.255799          0.251169          0.246623
## 3          0.259618          0.254919          0.250305          0.245774
## 4          0.296706          0.291336          0.286063          0.280885
## 5          0.210219          0.202216          0.194517          0.187112
## 6          0.648311          0.640952          0.633677          0.626484
##   Ccompartment_1.22 Ccompartment_1.23 Ccompartment_1.24
## 1          0.514588          0.505274          0.496129
## 2          0.242159          0.237776          0.233472
## 3          0.241326          0.236958          0.232669
## 4          0.275801          0.270809          0.265907
## 5          0.179988          0.173136          0.166544
## 6          0.619372          0.612342          0.605391

Check the time-dependent sensitivity measures

{r, eval=TF for(i in 2:24){ tell(x, out[,i+5]) plot(x, main = paste("Time = ", i-1, "hr"), xlim = c(0, 1), ylim = c(0, 1)) abline(0,1) # non-linear and/or non-monotonic abline(0,0.5, lty = 2) # monotonic abline(0,0.1, lty = 3) # almost linear date_time<-Sys.time() while((as.numeric(Sys.time()) - as.numeric(date_time))<0.5){} }

Data manipulate (Transfer to tidydata format)

index <- which(names(out) == "Ccompartment_1.1" | names(out) == "Ccompartment_1.24")
X <- apply(out[,index[1]:index[2]], 2, quantile,  c(0.5, 0.025, 0.975))
dat <- t(X)
colnames(dat) <- c("median", "LCL", "UCL")
df <- as.data.frame(dat)
df$time <- seq(0, 23, 1)
head(df)
##                     median       LCL      UCL time
## Ccompartment_1.1 0.0000000 0.0000000 0.000000    0
## Ccompartment_1.2 0.4717685 0.2386066 1.237713    1
## Ccompartment_1.3 0.4795500 0.2719481 1.319638    2
## Ccompartment_1.4 0.4759115 0.2715558 1.306399    3
## Ccompartment_1.5 0.4696055 0.2654703 1.279288    4
## Ccompartment_1.6 0.4575730 0.2544477 1.256138    5

Visualization

ggplot(df, aes(x = time, y = median)) +
  geom_ribbon(aes(ymin = LCL, ymax = UCL), fill = "grey70", alpha = 0.5) + 
  geom_line()

3 pksensi

3.1 Monte Carlo

  1. Set parameter distributions (assign parms, dist, q.qarg)
parameters <- c("Vdist","kelim", "kgutabs", "Fgutabs")  
dist <- c("Normal_cv", "Normal_cv", "Normal_cv", "Uniform") # MCSim definition
q.arg <- list(list(6.13, 0.2),
            list(0.023, 0.2),
            list(2.18, 0.2),
            list(0.8, 1.0))
  1. Set experiment time-points, output variables, and conditions
outputs <- c("Ccompartment")
times <- seq(0, 480, 1)
conditions <- c("MW = 228.291", "Period = 24", "IngDose = 1.0")
  1. Modeling
set.seed(2222)
y<-solve_mcsim(mName = "pbtk1cpt.model.R", params = parameters, vars = outputs, monte_carlo = 1000,
               dist = dist, q.arg = q.arg, time = times, condition = conditions)
## Starting time: 2019-05-29 12:11:23
## * Created input file "sim.in".
## Execute: ./mcsim.pbtk1cpt.model.R.exe sim.in
## Ending time: 2019-05-29 12:11:25
dim(y)
## [1] 1000    1  481    1
# check input file
  1. Visualization

Plotting the Pk profile the x-axis is time (hr) and y-axis is concentration (uM)

pksim(y)

  1. Report
summary(y)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.0000  0.8438  1.1017  1.1741  1.4175  3.5375

3.1 FAST

  1. Set parameter distribution (assign parms, dist, q.qarg)
params <- c("Vdist","kelim", "kgutabs", "Fgutabs")  
q <- "qunif"  # R definition
q.arg <- list(list(min = Vdist * 0.5, max = Vdist * 2),
              list(min = kelim * 0.5, max = kelim * 2),
              list(min = kgutabs * 0.5, max = kgutabs * 2),
              list(min = 0.8, max = 1)) 
  1. Generate parameter space
set.seed(1234)
x <- rfast99(params = params, n = 500, q = q, q.arg = q.arg, replicate = 5)
dim(x$a) # c(Evaluation, replication, parameters)
## [1] 2000    5    4
par(mfrow = c(4,1), mar = c(2,2,1,1), oma = c(1,1,2,1))
for (i in 1:5)
{
  plot(x$a[,i,1], type = "l")
  plot(x$a[,i,2], type = "l")
  plot(x$a[,i,3], type = "l")
  plot(x$a[,i,4], type = "l")  
  mtext(paste("r =", i), NORTH<-3, line=0.4, cex=1.2, outer=TRUE)
  date_time<-Sys.time()
  while((as.numeric(Sys.time()) - as.numeric(date_time))<1){} 
}
  1. Set experiment time-points, output variables, and conditions
outputs <- c("Ccompartment")
times <- seq(432, 480, 1)
conditions <- c("MW = 228.291", "Period = 24", "IngDose = 1.0")
  1. Modeling
y <- solve_mcsim(x, mName = "pbtk1cpt.model.R",  params = params, time = times,  
                 vars = outputs, condition = conditions)
## Starting time: 2019-05-29 12:11:26
## * Created input file "sim.in".
## Execute: ./mcsim.pbtk1cpt.model.R.exe sim.in
## Ending time: 2019-05-29 12:11:36
  1. Visualization and decision
plot(y)

pksim(y)

check(y)
## 
## Sensitivity check ( Index > 0.05 )
## ----------------------------------
## First order:
##  Vdist kelim 
## 
## Interaction:
##  Vdist kelim 
## 
## Total order:
##  Vdist kelim 
## 
## Unselected factors in total order:
##  kgutabs Fgutabs 
## 
## 
## Convergence check ( Index > 0.05 )
## ----------------------------------
## First order:
##   
## 
## Interaction:
##   
## 
## Total order:
## 

Reference

He Y et al., (2009) Bisphenol A levels in blood and urine in a Chinese population and the personal factors affecting the levels. Environmental Research 109(5): 629-33

Hsieh N-H, Reisfeld B, Bois FY, Chiu WA. (2018) Applying a Global Sensitivity Analysis Workflow to Improve the Computational Efficiencies in Physiologically-Based Pharmacokinetic Modeling. Frontiers in Pharmacology 9:588.

Hsieh N-H, Reisfeld B, Chiu WA et al. (2019) pksensi: Global Sensitivity Analysis in Pharmacokinetic Modeling

Pujol, G., et al. (2018). Sensitivity: Global Sensitivity Analysis of Model Outputs.

Wambaugh J., et al. (2019) httk: High-Throughput Toxicokinetics