shinyUI(pageWithSidebar(
  headerPanel(
    list(HTML('<p style="color:#4C0B5F; font-size:24px" fontsize=14>build your PK model</p>' )),
    windowTitle="build PK model"),
  
  sidebarPanel(
    tabsetPanel(
      tabPanel("administration",
               radioButtons("administration", "",
                            c("iv bolus" = "bolus","iv infusion" = "infusion","oral" = "oral")),
               #               selectInput("administration","",c("iv bolus" = "bolus","iv infusion" = "infusion","oral" = "oral")),
               sliderInput("tfd", "time of first dose:", value=0, min=0, max = 20, step=1),
               sliderInput("nd", "Number of doses:", value=3, 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),
               conditionalPanel(condition = "input.administration == 'infusion'",
                                sliderInput("tinf", "Infusion time:", value = 1, min = 0, max = 5, step=0.2)
               )
      ),
      tabPanel("model",
               tabsetPanel(
                 tabPanel("absorption",
                          conditionalPanel(condition = "input.administration == 'oral'",
                                           radioButtons("absorption","",c("first order" = "1","zero order" = "0")),
                                           
                                           conditionalPanel(condition = "input.absorption == '1'",
                                                            sliderInput("ka", "absorption rate constant ka:", value = 0.8, min = 0, max = 4, step=0.1)
                                           ),
                                           
                                           conditionalPanel(condition = "input.absorption == '0'",
                                                            sliderInput("tk0", "absorption duration Tk0:", value = 3, min = 0, max = 10, step=0.5)
                                           ),
                                           
                                           conditionalPanel(condition = "input.absorption == '0'",
                                                            selectInput("delay0","delay",c("none" = "0","lag time" = "1")),
                                                            conditionalPanel(condition = "input.delay0 == '1'",
                                                                             sliderInput("tlag0", "lag time Tlag:", value = 1, min = 0, max = 10, step=0.5)
                                                            )
                                           ),
                                           
                                           
                                           conditionalPanel(condition = "input.absorption == '1'",
                                                            selectInput("delay1","delay",c("none" = "0","lag time" = "1","transit compartment" = "2")),
                                                            conditionalPanel(condition = "input.delay1 == '1'",
                                                                             sliderInput("tlag1", "lag time Tlag:", value = 1, min = 0, max = 10, step=0.5)
                                                            ),
                                                            
                                                            conditionalPanel(condition = "input.delay1 == '2'",
                                                                             sliderInput("mtt", "mean transit time Mtt:", value = 1, min = 0, max = 10, step=0.5),
                                                                             sliderInput("ntr", "number of compartments Ntr:", value = 2, min = 0.5, max = 10, step=0.5)
                                                            )
                                          ),
                                           br(),                                
                                           br(),                                
                                           br(),
                                           br()
                                           
                          )
                 ),
                 
                 tabPanel("distribution",
                          radioButtons("distribution","",c("1 compartment" = "1","2 compartments" = "2","3 compartments" = "3")),
                          sliderInput("v", "volume V:", value = 10, min = 1, max = 20, step=1),
                          conditionalPanel(condition = "input.distribution != '1'",
                                           sliderInput("k12", "transition rate constant k12:", value = 0.4, min = 0, max = 2, step=0.05),
                                           sliderInput("k21", "transition rate constant k21:", value = 0.2, min = 0, max = 2, step=0.05)
                          ),
                          conditionalPanel(condition = "input.distribution == '3'",
                                           sliderInput("k13", "transition rate constant k13:", value = 0.4, min = 0, max = 2, step=0.05),
                                           sliderInput("k31", "transition rate constant k31:", value = 0.2, min = 0, max = 2, step=0.05)
                          ),
                          br()
                          
                 ),
                 
                 tabPanel("elimination",
                          radioButtons("elimination","",c("linear" = "1","Michaelis Menten" = "2")),
                          conditionalPanel(condition = "input.elimination == '1'",
                                           sliderInput("k", "elimination rate constant k:", value = 0.2, min = 0, max = 2, step=0.05)
                          ),
                          conditionalPanel(condition = "input.elimination == '2'",
                                           sliderInput("vm", "Vm:", value = 1, min = 0, max = 5, step=0.05),
                                           sliderInput("km", "Km:", value = 1, min = 0, max = 5, step=0.05)
                          )
                 ))
      ),
      tabPanel("output",
               br(),
               #               selectInput("output","",c("concentration (Cc)" = "Cc","amount (Ac)" = "Ac")),
               #               br(),
               sliderInput("range", "time range", min = -10, max = 200, value = c(-5,100), step=5),
               br(),
               sliderInput("ngp", "grid size", min = 10, max = 1000, value = 200, step=10)
      ),
      tabPanel("settings",
               sliderInput("lsize", "line width", min = 0, max = 3, value = 0.75, step=0.25),
               br(),
               checkboxInput("log", "Plot y axis on log scale", value = FALSE)
      )
    )
  ),
  
  mainPanel(
    br(),
    tabsetPanel(
      tabPanel("Plot", plotOutput("plot")), 
      tabPanel("Table", tableOutput("table")),
#       tabPanel("Mlxtran", verbatimTextOutput("mlxtranFile")),
tabPanel("pkmodel.R", verbatimTextOutput("RFile")),
tabPanel("ui.R", pre(includeText("ui.R"))),
      tabPanel("server.R", pre(includeText("server.R"))),
      tabPanel("ReadMe", withMathJax(), includeMarkdown("ReadMe.Rmd"))
    )
  )
))
my.dir=getwd()
source("../initMlxR.R")  #initialization for simulx.R
setwd(my.dir)

pkmodel.text <- ("
res <- pkmodel(t,adm,p)

print(ggplot(data=res, aes(x=time, y=cc)) + geom_line(size=1) +
  xlab('time (h)') + ylab('concentration (mg/L)'))
")

shinyServer(function(input, output){
  r <- reactive({ 
    param.name=NULL
    param.value=NULL
    if (input$administration=="oral"){
      if (input$absorption=="1"){
        if (input$delay1=="1"){
          param.name=c(param.name,'Tlag')
          param.value=c(param.value,input$tlag1)
        }
        if (input$delay1=="2"){
          param.name=c(param.name,'Mtt','Ktr')
          param.value=c(param.value,input$mtt,(input$ntr+1)/input$mtt)
        }
        param.name=c(param.name,'ka')
        param.value=c(param.value,input$ka)
      }else{
        param.name=c(param.name,'Tk0')
        param.value=c(param.value,input$tk0)        
        if (input$delay0=="1"){
          param.name=c(param.name,'Tlag')
          param.value=c(param.value,input$tlag0)
        }
      }
    }
    param.name=c(param.name,'V')
    param.value=c(param.value,input$v)
    if (input$distribution!="1"){
      param.name=c(param.name,'k12','k21')
      param.value=c(param.value,input$k12,input$k21)
    }
    if (input$distribution=="3"){
      param.name=c(param.name,'k13','k31')
      param.value=c(param.value,input$k13,input$k31)
    }
    if (input$elimination=="1"){
      param.name=c(param.name,'k')
      param.value=c(param.value,input$k)
    }else{
      param.name=c(param.name,'Vm','Km')
      param.value=c(param.value,input$vm,input$km)      
    }
    p=list(name=param.name,value=param.value)
    t.value=seq(input$range[1],input$range[2],length.out=input$ngp)
    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)
    }
    if (input$administration == 'infusion'){
      adm$rate <- input$amt/input$tinf
    }
    res   <- pkmodel(time=t.value,dose=adm,parameter=p)
    model.text <- includeText("temp_model.txt")

    a.text <- 'adm <- list('
    if (input$nd==0){
      a.text <- 'adm <- list(amount=0, time=0'
    } else if(input$nd==1){
      a.text <- paste0('adm <- list(amount=',input$amt,', time=',input$tfd)
    } else{
      t1=input$tfd
      t2=input$ii*(input$nd-1)+t1
      a.text <- paste0('adm <- list(amount=',input$amt,
                       ', time=seq(',t1,', ',t2,', by=',input$ii,')')
    }
    if (input$administration == 'infusion'){
      a.text <- paste0(a.text,', tinf=',input$tinf,')')
    }else{
      a.text <- paste0(a.text,')')      
    }
    K <- length(param.value)
    p.text <- 'p <- c('
    for (k in (1:(K-1))){
      p.text <- paste0(p.text,param.name[k],'=',param.value[k],', ')
    }
    p.text <- paste0(p.text,param.name[K],'=',param.value[K],')')
    t.text <- paste0('t <- seq(',input$range[1],', ',input$range[2],
                     ', length=',length.out=input$ngp,')')
    pkmodel.text <- paste0(a.text,'\n',p.text,'\n',t.text,'\n',pkmodel.text)

    out <- list(res,model.text,pkmodel.text)
    return(out)
  })
 
  output$plot <- renderPlot({
    pl=ggplot(data=r()[[1]], aes(x=time, y=cc)) + geom_line(size=input$lsize)
    print(pl)
  })
  
  output$table <- renderTable({ r()[[1]] })
  output$mlxtranFile <- renderText(r()[[2]])
  output$RFile  <- renderText(r()[[3]])
})

Build your PK model

Select the administration route and the dosage regimen in the tab administration:

  • iv bolus, iv infusion, or oral administration,
  • time of first dose, number of doses, interdose interval, infusion time (only for infusion), amount.

Define the PK model in the tab model:

  • Define the absorption process for oral administration in the tab absorption:

    • zero-order or first-order absorption process with the associated paramameters (duration of absorption \(Tk0\) or absorption rate constant \(ka\))
    • lag time \(Tlag\)
    • transit compartment model with mean transit time \(Mtt\) and number of transit compartments \(Ntr\) (only for first-order absorption)
  • Define the distribution process in the tab distribution: 1, 2 or 3 compartments

  • Define the eliination process in the tab elimination: linear or Michaelis Menten elimination process

Define the output in the tab outputs:

  • select the time range where the predicted concentration is computed, select the number of time points of the grid where the predicted concentration is computed.

Set some settings in the tab settings: line width, linear or semi-log scale.