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

Plot

absorptionModel.txt

Download

[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)
depot(target=Ad3)

; 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)
depot(target=Ad6)

EQUATION:
if Ad3>0
  R3 = ka*(Ad3^alpha)
else
  R3 = 0
end
ddt_Ad3 = -R3
ddt_A3 = R3 - k*A3

R6 = Vm*Ad6/(Km+Ad6)
ddt_Ad6 = -R6
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

Download

#-------------------------------------------------------------------------
#  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(),
  sidebarMenu(id="tabs",
              menuItem("Plot", tabName="plot", icon=icon("line-chart"), selected=TRUE),
              menuItem("Table", tabName = "table", icon=icon("table")),
              menuItem("Codes",  icon = icon("file-text-o"),
                       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"))
              ),
              menuItem("ReadMe", tabName = "readme", icon=icon("mortar-board")),
              menuItem("About", tabName = "about", icon = icon("question"))
  ),
  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(
    tabItem(tabName = "readme",
            withMathJax(), 
            includeMarkdown("readMe.Rmd")
    ),
    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",                
                 downloadButton('downloadTable', 'Download'),
                 br(),br(),
                 tableOutput("table")
            )
    ),
    tabItem(tabName = "pkmodel",
            box( width = NULL, status = "primary", solidHeader = TRUE, title="absorptionModel.txt",                
                 downloadButton('downloadData1', 'Download'),
                 br(),br(),
                 pre(includeText("absorptionModel.txt"))
            )
    ),
    tabItem(tabName = "ui",
            box( width = NULL, status = "primary", solidHeader = TRUE, title="ui.R",
                 downloadButton('downloadData2', 'Download'),
                 br(),br(),
                 pre(includeText("ui.R"))
            )
    ),
    tabItem(tabName = "server",
            box( width = NULL, status = "primary", solidHeader = TRUE, title="server.R",
                 downloadButton('downloadData3', 'Download'),
                 br(),br(),
                 pre(includeText("server.R"))
            )
    ),
    tabItem(tabName = "about",
            includeMarkdown("../../about/about.Rmd")
    )
  )
)

dashboardPage(
  dashboardHeader(title = "Absorption processes"),
  sidebar,
  body
)

server.R

Download

#-------------------------------------------------------------------------
#  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{
      adm <- list(time=t1, amount=0)
    }
    #----------------------------------------------------  
    res <- simulx(model     = "absorptionModel.txt", 
                  parameter = p, 
                  output    = out, 
                  treatment = adm)
    #----------------------------------------------------    
    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