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
Table
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) 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
#------------------------------------------------------------------------- # 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
#------------------------------------------------------------------------- # 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