library(shiny) library(bslib) library(mrgsolve) library(dplyr) library(ggplot2) model_code <- ' $PARAM @annotated CL : 4.28 : Clearance (L/h) V : 93.4 : Volume of distribution (L) DBIL : 2.6 : Direct bilirubin (umol/L) TINF : 1.0 : Infusion duration (h) $CMT @annotated CENT : Central (mg) $MAIN double DBILref = 2.6; double CLi = CL * pow(DBIL / DBILref, -0.40); double Vi = V; D_CENT = TINF; $ODE dxdt_CENT = -(CLi / Vi) * CENT; $TABLE double CP = CENT / Vi; $CAPTURE CP CLi ' mod <- mcode("voriconazole_iv", model_code) app_theme <- bs_theme( version = 5, bootswatch = "flatly", primary = "#8b5cf6" ) |> bs_add_rules(" .metric-card { background: #f8f9fa; border-radius: 8px; padding: 15px; margin: 5px; text-align: center; border: 1px solid #dee2e6; } .metric-value { font-size: 24px; font-weight: bold; color: #2c3e50; } .metric-label { font-size: 12px; color: #7f8c8d; } .metric-success .metric-value { color: #10b981; } .metric-warning .metric-value { color: #f59e0b; } .metric-primary .metric-value { color: #8b5cf6; } .metric-info .metric-value { color: #0dcaf0; } .ref-box { background: #f0f4ff; border-left: 4px solid #8b5cf6; padding: 12px 16px; border-radius: 4px; margin-top: 10px; font-size: 13px; } .ref-box a { color: #8b5cf6; } ") ui <- page_sidebar( title = "Voriconazole IV PopPK Simulator — Critically Ill Patients", theme = app_theme, sidebar = sidebar( title = "Simulation Settings", width = 340, h6("Dosing"), checkboxInput("use_loading", "Include Loading Dose (300 mg)", value = TRUE), sliderInput("dose", "Maintenance Dose (mg)", min = 100, max = 400, value = 200, step = 50), sliderInput("interval", "Dosing Interval (h)", min = 8, max = 24, value = 12, step = 4), sliderInput("tinf", "Infusion Duration (h)", min = 0.5, max = 3.0, value = 1.0, step = 0.5), numericInput("n_days", "Duration (days)", value = 5, min = 1, max = 14), hr(), h6("Patient Characteristics"), sliderInput("dbil", "Direct Bilirubin (µmol/L)", min = 0.5, max = 15.0, value = 2.6, step = 0.5), hr(), checkboxInput("log_scale", "Log Scale (Y-axis)", value = FALSE) ), navset_card_tab( title = "Voriconazole IV PK Simulator", full_screen = TRUE, nav_panel("Simulation", layout_column_wrap( width = 1/4, fill = FALSE, div(class="metric-card metric-success", div(class="metric-value", textOutput("cmax")), div(class="metric-label","Cmax,ss (µg/mL)")), div(class="metric-card metric-warning", div(class="metric-value", textOutput("ctrough")), div(class="metric-label","Ctrough,ss (µg/mL)")), div(class="metric-card metric-primary", div(class="metric-value", textOutput("auc")), div(class="metric-label","AUC0-τ,ss (µg·h/mL)")), div(class="metric-card metric-info", div(class="metric-value", textOutput("thalf")), div(class="metric-label","t½ (h)")) ), plotOutput("pkPlot", height = "500px") ), nav_panel("Model Information", markdown(" ## Voriconazole IV — Population Pharmacokinetic Model **Source:** Chen et al. (2015) *Biol. Pharm. Bull.* 38:996-1004 **Population:** Chinese critically ill adult ICU patients with pulmonary diseases (n=62, 240 observations) **Structure:** One-compartment model with first-order elimination (IV infusion) **Software:** NONMEM VI with FOCE+I ### Population PK Parameters (Final Model) | Parameter | Estimate | 95% CI | Bootstrap Median | |-----------|----------|--------|-----------------| | CL (L/h) | 4.28 | 3.48–5.08 | 4.30 | | Vd (L) | 93.4 | 79.4–107.4 | 93.4 | | θ_DBIL | −0.40 | −0.69 to −0.11 | −0.37 | | IIV CL (%) | 72.94 | — | 72.67 | | IIV Vd (%) | 26.50 | — | 26.93 | | Residual (%) | 13.0 | — | 12.67 | ### Covariate Model - **CL = 4.28 × (DBIL / 2.6)^(−0.40)** - Higher direct bilirubin → reduced clearance (impaired hepatic function) - 1-fold increase in DBIL above average → ~24% decrease in CL ### Therapeutic Drug Monitoring - **Target trough (Cmin):** 1.5–4.0 µg/mL - **>80% efficacy probability** at Cmin ≥ 1.5 µg/mL - **<15% grade 2 hepatotoxicity** at Cmin ≤ 4.0 µg/mL - Narrower window vs. non-critically ill patients ### Dosing Recommendations - **Loading:** 300 mg IV then maintenance q12h - **150 mg BID:** 99.76% in target range (mostly 1.5–2.5 µg/mL) - **200 mg BID:** 98.76% in target range (mostly 2.5–4.0 µg/mL) - 200 mg preferred for acute/critical; 150 mg for mild/moderate infection ")), nav_panel("References", div(class = "ref-box", tags$h5("\U0001f4da Key References"), tags$ol( tags$li("Chen W, Xie H, Liang F, et al. (2015) Population Pharmacokinetics in China: The Dynamics of Intravenous Voriconazole in Critically Ill Patients with Pulmonary Disease. Biol Pharm Bull 38:996-1004"), tags$li("Levêque D, Nivoix Y, Jehl F, Herbrecht R. (2006) Clinical pharmacokinetics of voriconazole. Int J Antimicrob Agents 27:274-284"), tags$li("Liu P, Mould DR. (2014) Population pharmacokinetic analysis of voriconazole and anidulafungin in adult patients with invasive aspergillosis. Antimicrob Agents Chemother 58:4718-4726"), tags$li("Han K, et al. (2011) Population pharmacokinetic evaluation with external validation and Bayesian estimator of voriconazole in liver transplant recipients. Clin Pharmacokinet 50:201-214") ), tags$h5("\U0001f48a Therapeutic Context"), tags$ul( tags$li(tags$strong("Class:"), " Triazole antifungal (second-generation, fluconazole derivative)"), tags$li(tags$strong("Indication:"), " Invasive aspergillosis, candidemia, Fusarium/Scedosporium infections"), tags$li(tags$strong("Route:"), " IV (this model), also available oral (high bioavailability ~96%)"), tags$li(tags$strong("Metabolism:"), " Hepatic via CYP2C19 (primary), CYP2C9, CYP3A4; nonlinear at higher doses"), tags$li(tags$strong("Key covariates:"), " CYP2C19 polymorphism, hepatic function (DBIL), body weight"), tags$li(tags$strong("TDM:"), " Recommended due to high PK variability; target Cmin 1.5-4.0 µg/mL in ICU") ) )) ), div(style = "text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #e9ecef; color: #6c757d; font-size: 12px;", "Powered by ", tags$a(href="https://www.pkpdbuilder.com", target="_blank", style="color: #8b5cf6; font-weight: 500;", "PKPDBuilder.com"), " \u2022 Built by Sunny \u2600\ufe0f (Husain Attarwala's AI Assistant)", br(), tags$span(style="font-size: 10px;", "For research and educational purposes only. Not for clinical decision-making.")) ) server <- function(input, output, session) { sim_data <- reactive({ # Build event schedule if (input$use_loading) { # Loading dose first, then maintenance starting at next interval ev_load <- ev(amt = 300, cmt = 1, rate = 300/input$tinf, time = 0) ev_maint <- ev(amt = input$dose, cmt = 1, rate = input$dose/input$tinf, time = input$interval, ii = input$interval, addl = (input$n_days * 24/input$interval) - 2) ev_all <- ev_load + ev_maint } else { ev_all <- ev(amt = input$dose, cmt = 1, rate = input$dose/input$tinf, ii = input$interval, addl = (input$n_days * 24/input$interval) - 1) } mod %>% param(DBIL = input$dbil, TINF = input$tinf) %>% ev(ev_all) %>% mrgsim(end = input$n_days * 24, delta = 0.1) %>% as.data.frame() %>% mutate(time_h = time) }) # Compute steady-state metrics from last dosing interval ss_data <- reactive({ d <- sim_data() last_dose_time <- max(0, (input$n_days * 24) - input$interval) d %>% filter(time >= last_dose_time, time <= last_dose_time + input$interval) }) output$cmax <- renderText({ sprintf("%.2f", max(ss_data()$CP, na.rm=TRUE)) }) output$ctrough <- renderText({ sprintf("%.2f", min(ss_data()$CP, na.rm=TRUE)) }) output$auc <- renderText({ d <- ss_data() if (nrow(d) < 2) return("--") auc <- sum(diff(d$time) * (head(d$CP,-1) + tail(d$CP,-1))/2) sprintf("%.1f", auc) }) output$thalf <- renderText({ CLi <- 4.28 * (input$dbil / 2.6)^(-0.40) Vi <- 93.4 sprintf("%.1f", log(2) / (CLi / Vi)) }) output$pkPlot <- renderPlot({ d <- sim_data() p <- ggplot(d, aes(x = time_h, y = CP)) + annotate("rect", xmin=-Inf, xmax=Inf, ymin=1.5, ymax=4.0, fill="#10b981", alpha=0.12) + geom_hline(yintercept = c(1.5, 4.0), linetype = "dashed", color = "#10b981", alpha=0.6) + annotate("text", x = max(d$time_h)*0.02, y = 4.3, label = "Therapeutic: 1.5-4.0 \u00b5g/mL", hjust=0, size=3.5, color="#10b981") + geom_line(color = "#8b5cf6", linewidth = 0.8) + labs(x = "Time (hours)", y = "Concentration (\u00b5g/mL)", title = paste0("Voriconazole IV ", input$dose, " mg Q", input$interval, "H", if(input$use_loading) " (300 mg loading)" else "")) + theme_minimal(base_size = 14) if (input$log_scale) p <- p + scale_y_log10() p }) } shinyApp(ui = ui, server = server)