Exploring the Capabilities of ChatGPT: A Step-by-Step Guide to Creating a Pharmacokinetic Analysis Shiny App

With the introduction of ChatGPT I was interested to learn how ChatGPT in pharmacometrics might be applied and how this will impact my code writing tasks, especially for doing pharmacokinetic analysis and creating a starting point for basic R applications. My objective of this post was to see whether ChatGPT could write the R code for a shiny application that is capable of a basic non-compartmental analysis, calculating the Cmax, Tmax, and AUC (linear interpolation) of a PK profile.

After creating a free account on https://chat.openai.com/ I wrote the following question:

  • Can you write a short introduction into ChatGPT.
  • It must contain the R code to create a shiny application to be used for a non-compartmental analysis of pharmacokinetic data
  • The data starts at time 0
  • The time column in the data is TIME, the concentration column in the data is CONC
  • The data should be uploaded via a file
  • The application should be able to calculate the maximal concentration, the time to the maximal concentration, and the area under the time-concentration curve using the linear trapezoid interpolation method.
  • Results should be presented in a graph

It’s reply is presented below.


ChatGPT is a large language model developed by OpenAI that can generate human-like text. It has been trained on a diverse range of internet text and can answer questions, write stories, and even code.

Here is an example of R code that creates a shiny application for non-compartmental analysis of pharmacokinetic data using linear trapezoid interpolation:

library(shiny)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Pharmacokinetic Analysis"),
  sidebarLayout(
    sidebarPanel(
      fileInput("data", "Upload data file"),
      actionButton("calculate", "Calculate")
    ),
    mainPanel(
      plotOutput("plot"),
      verbatimTextOutput("results")
    )
  )
)

server <- function(input, output) {
  data <- reactive({
    req(input$data)
    read.csv(input$data$datapath, header = TRUE)
  })
  
  observeEvent(input$calculate, {
    # Calculate maximal concentration
    Cmax <- max(data()$CONC)
    
    # Calculate time to maximal concentration
    Tmax <- data()$TIME[data()$CONC == Cmax]
    
    # Calculate area under the time-concentration curve
    AUC <- trapz(data()$TIME, data()$CONC)
    
    # Output results
    output$results <- renderPrint({
      cat("Maximal concentration: ", Cmax, "\n")
      cat("Time to maximal concentration: ", Tmax, "\n")
      cat("Area under the time-concentration curve: ", AUC)
    })
    
    # Plot results
    output$plot <- renderPlot({
      ggplot(data(), aes(x = TIME, y = CONC)) +
        geom_line() +
        labs(title = "Pharmacokinetic Profile", x = "Time", y = "Concentration")
    })
  })
}

shinyApp(ui, server)

This application allows the user to upload a data file containing columns named “TIME” and “CONC” and then calculates the maximal concentration, the time to the maximal concentration, and the area under the time-concentration curve using the linear trapezoid interpolation method. The results are presented in a graph. The user will press the “calculate” button to see the results.


However, running this code will give you the error that the trapz function was not found. Let’s ask:

  • the function trapz is not recognized

I apologize for the confusion, trapz is not a built-in R function, it comes from the pracma library, which is not loaded by default. You will need to install and load the pracma library before using the trapz function. You can do this by running the following code:

install.packages("pracma")
library(pracma)

You will have to include this line of code before the one that uses the trapz function in your shiny application.

server <- function(input, output) {
  data <- reactive({
    req(input$data)
    read.csv(input$data$datapath, header = TRUE)
  })
  library(pracma)
  observeEvent(input$calculate, {
    # Calculate maximal concentration
    Cmax <- max(data()$CONC)
    
    # Calculate time to maximal concentration
    Tmax <- data()$TIME[data()$CONC == Cmax]
    
    # Calculate area under the time-concentration curve
    AUC <- trapz(data()$TIME, data()$CONC)
    .
    .
    .
  })
}

By loading the library, you will be able to use the trapz() function to calculate the area under the curve (AUC) using the linear trapezoid interpolation method.


After copying the code to Rstudio and importing a csv file with a TIME and CONC column, this is the application that it has created. Looks great, doesn’t it?


My conclusion

The ease of use and the clean R code that has been generated for this simple project is a game-changer. There is no need to go to Google or StackOverflow for every question or to get a piece of template code. Furthermore, ChatGPT has already shown to also generate the code for NONMEM models and I can only imagine what the impact will be for the field of pharmacometrics. As always, a modeller/coder should critically check the code as there will be errors present that need to be fixed manually, but ChatGPT is capable of assisting you in fixing those errors as well.

I think the biggest disadvantage is that even though the responses of ChatGPT always sound convincing, they may be completely wrong. Some examples of code that I have requested just did not make sense and threw errors, even after repeatedly asking for improvements and specifying what was wrong. Especially for junior coders this might give a false sense of confidence that the backbone of their code is correct.

Let’s see how ChatGPT will be used in pharmacometrics in 2023!

p.s. the title of this post was generated by ChatGPT as well.

2 thoughts on “Exploring the Capabilities of ChatGPT: A Step-by-Step Guide to Creating a Pharmacokinetic Analysis Shiny App

  1. Laurence Reply

    This is amazing! Thank you for writing this post and opening my eyes to the possibilities of using ai in writing code. I came across this post while searching whether ai could help me generate code to create hysteresis plots for pk-pd. The funny coincidence is actually that you were also the one who showed me the online guides that helped me write the R code for those plots over a year ago!
    Thanks again for your tutoring and great posts. Keep them coming! 🙂

    • MJvanEsdonk Post authorReply

      Thanks Laurence! Much appreciated

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.