A one-compartment model for oral administration with linear elimination is used in this application.

Let $$A_d(t)$$ and $$A_c(t)$$ be, respectively, the amounts in the depot and central compartments.

We display the concentration in the central compartment $$C_c(t) = A_c(t)/V$$, where $$V=1$$ in this example.

Several absorption processes can be selected:

1. first order

\begin{aligned} \dot{A_d}(t) & = -ka \, A_d(t) \\ \dot{A_c}(t) & = ka \, A_d(t) - k \, A_c(t) \end{aligned}

2. zero order

\begin{aligned} \dot{A_d}(t) & = - R_0 \\ \dot{A_c}(t) & = R_0 - k \, A_c(t) \end{aligned} where $$R_0 = D/Tk0$$ if $$A_d(t)>0$$ and $$R_0 = 0$$ otherwise.

3. alpha order

\begin{aligned} \dot{A_d}(t) & = - R_\alpha \\ \dot{A_c}(t) & = R_\alpha - k \, A_c(t) \end{aligned} where $$R_\alpha = ka \, A_d(t)^\alpha$$ if $$A_d(t)>0$$ and $$R_\alpha = 0$$ otherwise.

You can check that an $$\alpha$$ order absorption process is

• a zero order absorption process if $$\alpha=0$$
• a first order absorption process if $$\alpha=1$$

4. sequential zero order - first order

A fraction $$F_0$$ of the dose $$D$$ is first absorbed with a zero-order absorption process during a time $$Tk0$$, then, the remaining fraction $$1-F_0$$ is absorbed with a first order absorption order process with rate constant $$\alpha$$.

5. simultaneous zero order - first order

A fraction $$F_0$$ of the dose $$D$$ is absorbed with a zero-order absorption process during a time $$Tk0$$. The remaining fraction $$1-F_0$$ is simultaneously absorbed with a first order absorption order process with rate constant $$\alpha$$.

6. saturated (Michaelis Menten)

\begin{aligned} \dot{A_d}(t) & = - R_m \\ \dot{A_c}(t) & = R_m - k \, A_c(t) \end{aligned} where $$R_m(t) = V_m \, A_d(t)/(K_m + A_d(t))$$.

• Use the menu Plot to plot the PK profiles and modify either the PK parameters or the dosage regimen (default is a single dose at time 0)

• Use the menu Table to create and save a table with the concentration values.

• Use the menu Codes to display and download the Mlxtran code, the ui.R and server.R files used for this application

### absorptionModel.txt

[LONGITUDINAL]
input = {ka, Tk0, alpha, F0, Vm, Km, V, k}

PK:

; first order
compartment(cmt=1, amount=A1)
oral(cmt=1, ka)
elimination(cmt=1, k)

; zero order
tk0 = max(Tk0, 0.0001)
compartment(cmt=2, amount=A2)
oral(cmt=2, Tk0=tk0)
elimination(cmt=2, k)

; alpha order (ODE)

; sequential zero order - first order
compartment(cmt=4, amount=A4)
oral(cmt=4, Tk0=tk0, p=F0)
oral(cmt=4, ka, Tlag=tk0, p=1-F0)
elimination(cmt=4, k)

; mixed zero order - first order
compartment(cmt=5, amount=A5)
oral(cmt=5, Tk0=tk0, p=F0)
oral(cmt=5, ka, p=1-F0)
elimination(cmt=5, k)

; saturated absorption (ODE)

EQUATION:
else
R3 = 0
end
ddt_A3 = R3 - k*A3

ddt_A6 = R6 - k*A6

C1=A1/V
C2=A2/V
C3=A3/V
C4=A4/V
C5=A5/V
C6=A6/V


### ui.R

#-------------------------------------------------------------------------
#  This application is governed by the CeCILL-B license.
#  You can  use, modify and/ or redistribute this code under the terms
#  of the CeCILL license:  http://www.cecill.info/index.en.html
#
#  Marc Lavielle, Inria Saclay
#  April 29th, 2015
#-------------------------------------------------------------------------

library(shinydashboard)

sidebar <- dashboardSidebar(
hr(),
menuSubItem("Mlxtran", tabName = "pkmodel", icon = icon("angle-right")),
menuSubItem("ui.R", tabName = "ui", icon = icon("angle-right")),
menuSubItem("server.R", tabName = "server", icon = icon("angle-right"))
),
),
hr(),
conditionalPanel("input.tabs=='plot'",
fluidRow(
column(1),
column(10,
checkboxInput("first", "First order", TRUE),
checkboxInput("zero", "Zero order", TRUE),
checkboxInput("al", "alpha order", FALSE),
checkboxInput("sequential", "Sequential (0-1)", FALSE),
checkboxInput("mixed", "Simultaneous (0-1)", FALSE),
checkboxInput("saturated", "Saturated", FALSE),
checkboxInput("legend", "Legend", TRUE)
)
)
)
)

body <- dashboardBody(
tabItems(
withMathJax(),
),
tabItem(tabName = "plot",
fluidRow(
column(width = 4,
tabBox( width = NULL,
tabPanel(h5("parameters"),
conditionalPanel(condition="input.sequential=='1' | input.mixed=='1' | input.first=='1' | input.alpha=='1' ",
sliderInput("ka", "ka:", value = 0.5, min = 0.1, max = 3, step=0.1)
),
conditionalPanel(condition="input.sequential=='1' | input.mixed=='1' | input.zero=='1' ",
sliderInput("Tk0", "Tk0:", value = 5, min = 0, max = 10, step=0.5)
),
conditionalPanel(condition="input.al=='1'",
sliderInput("alpha", "alpha:", value = 0.5, min = 0, max = 2, step=0.1)
),
conditionalPanel(condition="input.sequential=='1' | input.mixed=='1' ",
sliderInput("F0", "F0:", value = 0.5, min = 0, max = 1, step=0.1)
),
conditionalPanel(condition="input.saturated=='1'",
sliderInput("Vm", "Vm:", value = 0.9, min = 0, max = 2, step=0.1),
sliderInput("Km", "Km:", value = 0.2, min = 0, max = 1, step=0.1)
),
sliderInput("k", "k:", value = 0.1, min = 0, max = 2, step=0.05)
),
tabPanel(h5("dosage"),
sliderInput("tfd", "Time of first dose:", value=0, min=0, max = 20, step=1),
sliderInput("nd", "Number of doses:", value=1, min=0, max = 10, step=1),
sliderInput("ii", "Interdose interval:", value = 9, min = 0.5, max = 15, step=0.5),
sliderInput("amt", "Amount:", value = 5, min = 0, max = 20, step=1)
)
)),
column(width = 8,
box(  width = NULL, plotOutput("plot",height="500px"), collapsible = TRUE,
title = "Plot", status = "primary", solidHeader = TRUE)
))
),
tabItem(tabName = "table",
box( width = NULL, status = "primary", solidHeader = TRUE, title="Table",
br(),br(),
tableOutput("table")
)
),
tabItem(tabName = "pkmodel",
box( width = NULL, status = "primary", solidHeader = TRUE, title="absorptionModel.txt",
br(),br(),
pre(includeText("absorptionModel.txt"))
)
),
tabItem(tabName = "ui",
box( width = NULL, status = "primary", solidHeader = TRUE, title="ui.R",
br(),br(),
pre(includeText("ui.R"))
)
),
tabItem(tabName = "server",
box( width = NULL, status = "primary", solidHeader = TRUE, title="server.R",
br(),br(),
pre(includeText("server.R"))
)
),
)
)
)

dashboardPage(
sidebar,
body
)

### server.R

#-------------------------------------------------------------------------
#  This application is governed by the CeCILL-B license.
#  You can  use, modify and/ or redistribute this code under the terms
#  of the CeCILL license:  http://www.cecill.info/index.en.html
#
#  Marc Lavielle, Inria Saclay
#  April 29th, 2015
#-------------------------------------------------------------------------

library(shinydashboard)
library(mlxR)

shinyServer(function(input, output){
r <- reactive({
p <- c(ka=input$ka, Tk0=input$Tk0, alpha=input$alpha, F0=input$F0, Vm=input$Vm, Km=input$Km, V=1, k=input$k) t.value=seq(0,24,length.out=241) out <- list(name=c("C1", "C2", "C3", "C4", "C5", "C6"), time=t.value) t1=input$tfd
t2=input$ii*(input$nd-1)+t1
if (t2>=t1){
t.dose=seq(t1,t2,by=input$ii) adm <- list(time=t.dose, amount=input$amt)
}else{
}
#----------------------------------------------------
res <- simulx(model     = "absorptionModel.txt",
parameter = p,
output    = out,
#----------------------------------------------------
return(res)
})

gg_color_hue <- function(n) {
hues = seq(15, 375, length=n+1)
hcl(h=hues, l=65, c=100)[1:n]}
vc=gg_color_hue(6)[c(1,4,2,3,6,5)]
names(vc)=letters[1:6]
lc <- c("first order", "zero order", "alpha order",
"sequential 0-1", "simultaneous 0-1", "saturated")
names(vc)=letters[1:6]

output$plot <- renderPlot({ r <- r() npl <- 0 vdisp <- rep(FALSE,6) pl=ggplotmlx() if (input$first==TRUE){
pl=pl + geom_line(data=r$C1, aes(x=time, y=C1, colour="a"), size=1) vdisp[1] <- TRUE} if (input$zero==TRUE){
pl=pl + geom_line(data=r$C2, aes(x=time, y=C2, colour="b"), size=1) vdisp[2] <- TRUE} if (input$al==TRUE){
pl=pl + geom_line(data=r$C3, aes(x=time, y=C3, colour="c"), size=1) vdisp[3] <- TRUE} if (input$sequential==TRUE){
pl=pl + geom_line(data=r$C4, aes(x=time, y=C4, colour="d"), size=1) vdisp[4] <- TRUE} if (input$mixed==TRUE){
pl=pl + geom_line(data=r$C5, aes(x=time, y=C5, colour="e"), size=1) vdisp[5] <- TRUE} if (input$saturated==TRUE){
pl=pl + geom_line(data=r$C6, aes(x=time, y=C6, colour="f"), size=1) vdisp[6] <- TRUE} pl <- pl + ylab("Amount = Concentration (V=1)") pl <- pl + scale_colour_manual(values=vc[vdisp], labels=lc[vdisp]) if (input$legend==TRUE){
pl <- pl + theme(legend.position=c(.65, 0.95), legend.justification=c(0,1), legend.title=element_blank())
}else{
pl <- pl + theme(legend.position="none")
}
if (input$nd==1) pl <- pl +ylim(c(0,input$amt))
print(pl)
})

rr <- reactive({
r <- r()
rr <- r[[1]]
for (k in (2:6))
rr <- merge(rr, r[[k]])
return(rr)
})

output$table <- renderTable({ rr() }) output$downloadTable <- downloadHandler(
filename = "table.csv",
content = function(file) {
write.csv(rr(), file)
}
)

})

This application is governed by the CeCILL-B license.
You can use, modify and/or redistribute these codes under the terms of the CeCILL license.

This Shiny application requires the mlxR package.

Marc Lavielle
Inria Saclay, Popix team
April 29th, 2015