--- title: "Risk Stratification and IOL Power Calculation Tool for Marfan Syndrome Patients with Ectopia Lentis" author: Xinshen date: 2025/05/17 date-format: long filters: - shinylive --- ```{shinylive-r} #| standalone: true #| viewerHeight: 200 library(shiny) library(ggplot2) library(shinyjs) ui <- fluidPage( useShinyjs(), actionButton("cal", "Estimate IOL Power"), imageOutput("img1_ui"), imageOutput("img2_ui"), imageOutput("img3_ui"), uiOutput("words") ) server <- function(input, output, session) { rdata_file1 <- tempfile(fileext = ".png") correct_url1 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup1.png" download.file(correct_url1, destfile = rdata_file1, mode = "wb") rdata_file2 <- tempfile(fileext = ".png") correct_url2 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/Logo-Department.png" download.file(correct_url2, destfile = rdata_file2, mode = "wb") rdata_file3 <- tempfile(fileext = ".png") correct_url3 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup2.png" download.file(correct_url3, destfile = rdata_file3, mode = "wb") output$img1_ui <- renderImage({ list( src = rdata_file1, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$img2_ui <- renderImage({ list( src = rdata_file2, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$img3_ui <- renderImage({ list( src = rdata_file3, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) observeEvent(input$cal, { shinyjs::show("img1_ui") output$words <- renderUI({ HTML("Calculation completed!") }) }) } shinyApp(ui = ui, server = server) ``` ```{shinylive-r} #| standalone: true #| viewerHeight: 2000 library(bslib) library(shiny) library(gt) library(tidyverse) library(magick) library(shinyjs) library(DT) library(ggplot2) #####IOL power calculation ######predicted ALP ALP_min24 <- function(AL, K1, K2){ Km <- 2/(1/K1 + 1/K2) CCR <- 337.5/Km ALP <- 0.26755 *AL -0.35626 * CCR +1.56317 return(ALP) } ##IOL : PCB00/ZCB00 = 1 ##Procedure :MCTR = 1 ALP_maj24 <- function(WTW, Age, IOL, Procedure){ ALP <- 0.190810 * WTW + 0.007952 * Age + 0.297651 * IOL - 0.263585 * Procedure return(ALP) } #####predicted ELP ELP_min24 <- function(ALP, AL, K1, K2, WTW){ Km <- 2/(1/K1 + 1/K2) CCR <- 337.5/Km H <- CCR - ((CCR)^2 - ((WTW - 1)/2)^2)^(1/2) ELP <- ALP *0.45967 + H * 0.79294 + AL *0.27593 -0.23519 *CCR -3.49273 return(ELP) } ELP_maj24 <- function(ALP, AL, K1, K2){ Km <- 2/(1/K1 + 1/K2) CCR <- 337.5/Km ELP <- ALP * 0.7368 + 0.3152 * AL -0.5416 * CCR -1.5633 return(ELP) } ####adjust AL AL_optimized_min24 <- function(AL){ AL_O <- 1.10766 * AL - 2.17799 return(AL_O) } AL_optimized_maj24 <- function(AL){ AL_O <- 0.99574 * AL + 0.53407 return(AL_O) } #######MFFF refraction <- function(IOL_power, K1, K2, ELP, AL){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) R <- R*0.001 ELP <- ELP* 0.001 AL <- AL*0.001 m <- na/(AL - ELP) - IOL_power mm <- na/m + ELP mmm <- na/mm - (ncm1/R) mmmm <- 1/mmm + V ref <- 1/mmmm return(ref) } ######calculate IOL power IOL_power_ref_0 <- function(K1, K2, ELP, AL){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) R <- R*0.001 ELP <- ELP* 0.001 AL <- AL*0.001 aa <- (na/(AL - ELP)) bb <- na/(na/(ncm1/R) - ELP) P <- aa - bb return(P) } IOL_power_ref <- function(ref, K1, K2, ELP, AL){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) R <- R*0.001 ELP <- ELP* 0.001 AL <- AL*0.001 aa <- (na/(AL - ELP)) cc <- ncm1/R + 1/(1/ref - V) bb <- na/(na/cc - ELP) P <- aa - bb return(P) } ####T2_optimizAL refraction_T2 <- function(IOL_power, K1, K2, A, AL, AL_O){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) L <- AL ifelse( L <= 24.2, LCOR <- L, ifelse(L <36.2, LCOR <- 1.716*L-3.446-0.0237*L*L, LCOR <- 27.62) ) H <- -10.326 + 0.32630 * AL + 0.13533 * K ACDcon <- 0.62467*A - 68.747 offset_SRTK <- ACDcon - 3.336 ACDest <- (H + offset_SRTK) * 0.001 ACDest <- ACDest rethick <- 0.65696 - 0.02020 * L LOPT <- (L + rethick) * 0.001 R <- R *0.001 AL_O <- AL_O * 0.001 m <- na/(AL_O - ACDest) - IOL_power mm <- na/m + ACDest mmm <- na/mm - ncm1/R mmmm <- 1/mmm + V ref <- 1/mmmm return(ref) } ######calculate IOL power IOL_power_ref_0_T2 <- function(K1, K2, A, AL_O, AL){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) L <- AL ifelse( L <= 24.2, LCOR <- L, ifelse(L <36.2, LCOR <- 1.716*L-3.446-0.0237*L*L, LCOR <- 27.62) ) H <- -10.326 + 0.32630 * AL + 0.13533 * K ACDcon <- 0.62467*A - 68.747 offset_SRTK <- ACDcon - 3.336 ACDest <- (H + offset_SRTK) * 0.001 ACDest <- ACDest rethick <- 0.65696 - 0.02020 * L LOPT <- (L + rethick) * 0.001 R <- R *0.001 ELP <- ACDest AL_O <- AL_O * 0.001 aa <- (na/(AL_O - ELP)) bb <- na/(na/(ncm1/R) - ELP) P <- aa - bb return(P) } IOL_power_ref_T2 <- function(ref, K1, K2, AL_O, A, AL){ na <- 1.336 nc <- 1.333 ncm1 <- nc - 1 K <- 2/(1/K1 + 1/K2) V <- 0.012 R <- (337.5/K) L <- AL ifelse( L <= 24.2, LCOR <- L, ifelse(L <36.2, LCOR <- 1.716*L-3.446-0.0237*L*L, LCOR <- 27.62) ) H <- -10.326 + 0.32630 * AL + 0.13533 * K ACDcon <- 0.62467*A - 68.747 offset_SRTK <- ACDcon - 3.336 ACDest <- (H + offset_SRTK) * 0.001 ACDest <- ACDest rethick <- 0.65696 - 0.02020 * L LOPT <- (L + rethick) * 0.001 R <- R *0.001 ELP <- ACDest AL_O <- AL_O * 0.001 aa <- (na/(AL_O - ELP)) cc <- ncm1/R + 1/(1/ref - V) bb <- na/(na/cc - ELP) P <- aa - bb return(P) } Z_AL <- function(Age, AL){ aget <- Age alt <- AL Z_AL <- NA Z_AL <- ifelse(aget >= 18, (alt - 24.50)/1.03, ifelse(aget >= 17, (alt - 24.58)/1.14, ifelse(aget >= 16, (alt - 24.65)/1.22, ifelse(aget>= 15, (alt - 24.50)/1.21, ifelse(aget>=14, (alt - 24.41)/1.30, ifelse(aget>=13, (alt - 24.10)/1.17, ifelse(aget>= 12, (alt - 23.94)/1.08, ifelse(aget>= 11, (alt - 23.77)/1.03, ifelse(aget>= 10, (alt - 23.58)/1.01, ifelse( aget>= 9, (alt - 23.34)/0.89, ifelse( aget>=8, (alt - 23.06)/0.88, ifelse( aget>=7, (alt - 22.76)/0.79, ifelse( aget>=6, (alt - 22.49)/0.75, ifelse( aget>=5, (alt - 22.31)/0.68, ifelse( aget>=4, (alt - 22.15)/0.72, ifelse( aget>=3, (alt - 22.10)/0.72, cccc <- 1 ) ) ) ) ) ) ) ) ) ) ) )) ) )) return(Z_AL) } clustertree <- function(Age, Z_AL, AL, Apex, CCR){ cluster <- NA cluster <- ifelse(Age <12 & Z_AL <1.5 & CCR <8.5, "A", ifelse(Age <12 & Z_AL <1.5 & CCR >= 8.5 & Apex >=526, "A", ifelse(Age <12 & Z_AL <1.5 & CCR >= 8.5 & Apex <526, "B", ifelse(Age <12 & Z_AL >= 1.5 & Z_AL >= 9, "D", ifelse(Age <12 & Z_AL >= 2.6 & Z_AL < 9 , "B", ifelse(Age <12 & Z_AL >= 1.5 & Z_AL < 2.6 &CCR<8.1, "A", ifelse( Age <12 & Z_AL >= 1.5 & Z_AL < 2.6 &CCR>=8.1 &Apex >= 577, "A", ifelse(Age <12 & Z_AL >= 1.5 & Z_AL < 2.6 &CCR>=8.1 &Apex < 577, "B", ifelse( Age >= 12 & AL <28, "C", "D" ) ) ) ) ) ) ) )) return(cluster) } # Define UI for application that draws a histogram gender_female_male <- c("Female", "Male") eye_side <- c("Right", "Left") procedures <- c("MCTR", "CTR-CH", "SF-IOL") ui <- page_fixed( useShinyjs(), tags$style( " html, body { max-width: 1300px; /* 设置页面最大宽度 */ margin: auto; /* 居中 */ width: 100%; /* 确保宽度为 100% */ } "), layout_columns( col_widths = c(4, 8), card( full_screen = TRUE, imageOutput("img1_ui",, inline = TRUE), style = "margin-top: 10px; display: flex; justify-content: center; align-items: center;" ), card_body( # 使用 HTML 和 CSS 来设置字号、居中、首行缩进和两侧对齐 HTML( '

Welcome to the MFS with EL Clustering Tool! This website provides an innovative platform for risk stratification and treatment decision-making for patients with Marfan syndrome and ectopia lentis. Based on data from the EL cohort, our research leverages machine learning to identify four distinct clinical phenotypes, offering valuable insights into prognosis and therapeutic response. By integrating real-world data and combining it with published IOL power calculation tools, the platform supports clinicians in tailoring personalized treatment strategies, including postoperative PCO risk estimation and IOL power calculation.

' ) ) ) , card( full_screen = TRUE, card_body( fluidRow( column(4, textInput("name", label = span("Patient's name", class = "label custom-input"), value = "")), column(4, dateInput("dob", label = span("Patient's birthday", class = "label custom-input"), value = "1993-12-22")), column(4, selectInput("Gender", label = span("Patient's gender", class = "label custom-input"), gender_female_male)) ), fluidRow( column(4, selectInput("eyeside", label = span("Laterality", class = "label custom-input"), eye_side)), column(4, textInput("surger", label = span("Doctor's name", class = "label custom-input"), value = "")), column(4, dateInput("Sob", label = span("Surgery date", class = "label custom-input"), value = "2025-5-15")) ), fluidRow( column(4, numericInput("AL", label = span("AL (mm)", class = "label custom-input"), value = "24.03", step = 0.01)), column(4, numericInput("WTW", label = span("WTW (mm)", class = "label custom-input"), value = "12.32", step = 0.01)), column(4, numericInput("APEX", label = span("APEX (µm)", class = "label custom-input"), value = "553",step = 1)) ), fluidRow( column(4, numericInput("K1", label = span("K1 (D)", class = "label custom-input"), value = "41.21",step = 0.01)), column(4, numericInput("K2", label = span("K2 (D)", class = "label custom-input"), value = "42.33",step = 0.01)), column(4, numericInput("ref", label = span("Target refraction (D)", class = "label custom-input"), value = "-1",step = 0.01)) ), fluidRow( column(4,offset = 2, selectInput("procedure",label = span( "Procedure", class = "label custom-input"),choices = c("MCTR", "CTR-CH", "SF-IOL"))), column(4, selectInput("IOL_type",label = span( "IOL", class = "label custom-input"), choices = c("DCB00/ICB00/ZCB00", "SN60AT/SN60WF","Rayner 920H/970C")) ) ))) , card( actionButton("cal", label = span("Extimate cluster and calculate IOL power",class = "label custom-input"), class = "btn-success", icon = shiny::icon("calculator")) ), tags$div( id = "plot_div", style = "display:none;", layout_columns( col_widths = c(4, 8), card( div( style = "display: flex; justify-content: center; align-items: center; height: 100%;", uiOutput("words_cluster") ) ), card( div( style = "margin-top: 10px; display: flex; justify-content: center; align-items: center;", imageOutput("PCO_sur", inline = TRUE) ) ) ) ), tags$div( style = "display: flex; justify-content: center; align-items: center; height: 100%;", uiOutput("conditional_layout") ) ) server <- function(input, output, session) { rdata_file1 <- tempfile(fileext = ".png") correct_url1 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup1.png" download.file(correct_url1, destfile = rdata_file1, mode = "wb") rdata_file2 <- tempfile(fileext = ".png") correct_url2 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/Logo-Department.png" download.file(correct_url2, destfile = rdata_file2, mode = "wb") rdata_file3 <- tempfile(fileext = ".png") correct_url3 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup2.png" download.file(correct_url3, destfile = rdata_file3, mode = "wb") observeEvent(input$procedure, { if (input$procedure %in% c("MCTR", "CTR-CH")) { # If the first input is A or B, update second input to D and E updateSelectInput(session, "IOL_type", choices = c("DCB00/ICB00/ZCB00", "SN60AT/SN60WF")) } else if (input$procedure == "SF-IOL") { # If the first input is C, update second input to F updateSelectInput(session, "IOL_type", choices = "Rayner 920H/970C") } }) observeEvent(input$cal, { shinyjs::show(id = "plot_div") }) calculateValues <- eventReactive(input$cal, { if(input$Gender == "Female") { gg <- 0 } else { gg <- 1 } today <- Sys.Date() dob <- as.Date(input$dob) surgery_date <- as.Date(input$Sob) aa <- as.numeric(difftime(surgery_date, dob, units = "days")) / 365.25 ccrz <- 337.5/(2/(1/input$K1 + 1/input$K2)) # 执行全部计算逻辑,并将结果作为列表返回 ALP_M_P = if(input$AL > 24) { ALP_maj24(WTW = input$WTW, Age = aa, IOL = 1, Procedure = 1) } else { ALP_min24(AL = input$AL, K1 = input$K1, K2 = input$K2 ) } ALP_M_S = if(input$AL > 24) { ALP_maj24(WTW = input$WTW, Age = aa, IOL = 0, Procedure = 1) } else { ALP_min24(AL = input$AL, K1 = input$K1, K2 = input$K2 ) } ALP_C_P = if(input$AL > 24) { ALP_maj24(WTW = input$WTW, Age = aa, IOL = 1, Procedure = 0) } else { ALP_min24(AL = input$AL, K1 = input$K1, K2 = input$K2 ) } ALP_C_S = if(input$AL > 24) { ALP_maj24(WTW = input$WTW, Age = aa, IOL = 0, Procedure = 0) } else { ALP_min24(AL = input$AL, K1 = input$K1, K2 = input$K2 ) } ELP_M_P = if(input$AL > 24) { ELP_maj24(ALP = ALP_M_P, AL = input$AL, K1 = input$K1, K2 = input$K2) } else { ELP_min24(ALP = ALP_M_P, AL = input$AL, K1 = input$K1, K2 = input$K2, WTW = input$WTW) } ELP_M_S = if(input$AL > 24) { ELP_maj24(ALP = ALP_M_S, AL = input$AL, K1 = input$K1, K2 = input$K2) } else { ELP_min24(ALP = ALP_M_S, AL = input$AL, K1 = input$K1, K2 = input$K2, WTW = input$WTW) } ELP_C_P = if(input$AL > 24) { ELP_maj24(ALP = ALP_C_P, AL = input$AL, K1 = input$K1, K2 = input$K2) } else { ELP_min24(ALP = ALP_C_P, AL = input$AL, K1 = input$K1, K2 = input$K2, WTW = input$WTW) } ELP_C_S = if(input$AL > 24) { ELP_maj24(ALP = ALP_C_S, AL = input$AL, K1 = input$K1, K2 = input$K2) } else { ELP_min24(ALP = ALP_C_S, AL = input$AL, K1 = input$K1, K2 = input$K2, WTW = input$WTW) } AL_optimized = if(input$AL > 24) { AL_optimized_maj24(AL = input$AL) } else { AL_optimized_min24(AL = input$AL) } ZAL = Z_AL(Age = aa, AL = input$AL) clus = clustertree(AL = input$AL, Z_AL = ZAL, Age = aa, Apex = input$APEX, CCR = ccrz ) return(list( ALP_M_P = ALP_M_P, ALP_M_S = ALP_M_S, ALP_C_P = ALP_C_P, ALP_C_S = ALP_C_S, ELP_M_P = ELP_M_P, ELP_M_S = ELP_M_S, ELP_C_P = ELP_C_P, ELP_C_S = ELP_C_S, AL_optimized = AL_optimized, aa = aa, ZAL = ZAL, clus = clus )) } ) table_reactive <- eventReactive(input$cal,{ values <- calculateValues() aa <- values$aa clus <- values$clus if(aa <= 15){ if(clus == "A"){ AL_15 <- 1.67 * log10(aa +0.6) +21.71 }else{ if(clus == "B"){ AL_15 <- 7.2 * log10(aa +0.6) +19.69 }else{ AL_15 <- input$AL } } }else( AL_15 <- input$AL ) if(AL_15 > 24) { AL_optimized_15 <-AL_optimized_maj24(AL = AL_15) } else { AL_optimized_15 <-AL_optimized_min24(AL = AL_15) } table_M_S <- data.frame(x = c(NA, NA, NA, NA, NA, NA), y = NA, z = NA, d = NA, e = NA, f = NA, g =NA, t = NA, n = NA) colnames(table_M_S) <- c("IOL", "IOL Power", "Refraction", "AL", "K1", "K2", "WTW", "Gender", "ELP") table_M_S$IOL <- "SN60AT/SN60WT" table_M_S$AL <- input$AL table_M_S$K1 <- input$K1 table_M_S$K2 <- input$K2 table_M_S$WTW <- input$WTW table_M_S$Gender <- input$Gender table_M_S$ELP <- values$ELP_M_S IOLPref0_M_S <- IOL_power_ref_0(AL = input$AL, K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_S) table_M_S[6, 2] <- IOLPref0_M_S table_M_S[6, 3] <- 0 if(input$ref == 0){ med_IOLP_M_S <- as.numeric((round(IOLPref0_M_S/0.5))*0.5) M_S_list <- c(med_IOLP_M_S +1, med_IOLP_M_S+0.5, med_IOLP_M_S, med_IOLP_M_S-0.5,med_IOLP_M_S-1) table_M_S[1:5, 2] <- M_S_list table_M_S[1:5, 3] <- refraction( IOL_power = table_M_S[1:5, 2], K1 = table_M_S[1:5, 5], K2 = table_M_S[1:5, 6], ELP = table_M_S[1:5, 9], AL = table_M_S[1:5, 4])}else{ IOLP_M_S_ref <- IOL_power_ref( ref = input$ref, K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_S, AL = input$AL ) med_IOLP_M_S <- as.numeric((round(IOLP_M_S_ref/0.5))*0.5) M_S_list <- c(med_IOLP_M_S +1, med_IOLP_M_S+0.5, med_IOLP_M_S, med_IOLP_M_S-0.5,med_IOLP_M_S-1) table_M_S[1:5, 2] <- M_S_list table_M_S[1:5, 3] <- refraction( IOL_power = table_M_S[1:5, 2], K1 = table_M_S[1:5, 5], K2 = table_M_S[1:5, 6], ELP = table_M_S[1:5, 9], AL = table_M_S[1:5, 4])} tableM_S <- table_M_S tableM_S <- tableM_S[, 2:3] tableM_S_15 <- tableM_S tableM_S_15$`Refraction at 15y` <- refraction( IOL_power = tableM_S_15[,1], K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_S, AL = AL_15) tableM_S <- as.data.frame(tableM_S) tableM_S[, 1] <- round(tableM_S[, 1], 2) tableM_S[, 2] <- round(tableM_S[, 2], 2) tableM_S_15 <- as.data.frame(tableM_S_15) tableM_S_15[,1] <- round(tableM_S_15[,1],2) tableM_S_15[,2]<- round(tableM_S_15[,2],2) tableM_S_15[,3]<- round(tableM_S_15[,3],2) table_M_P <- data.frame(x = c(NA, NA, NA, NA, NA, NA), y = NA, z = NA, d = NA, e = NA, f = NA, g =NA, t = NA, n = NA) colnames(table_M_P) <- c("IOL", "IOL Power", "Refraction", "AL", "K1", "K2", "WTW", "Gender", "ELP") table_M_P$IOL <- "SN60AT/SN60WT" table_M_P$AL <- input$AL table_M_P$K1 <- input$K1 table_M_P$K2 <- input$K2 table_M_P$WTW <- input$WTW table_M_P$Gender <- input$Gender table_M_P$ELP <- values$ELP_M_P IOLPref0_M_P <- IOL_power_ref_0(AL = input$AL, K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_P) table_M_P[6, 2] <- IOLPref0_M_P table_M_P[6, 3] <- 0 if(input$ref == 0){ med_IOLP_M_P <- as.numeric((round(IOLPref0_M_P/0.5))*0.5) M_P_list <- c(med_IOLP_M_P +1, med_IOLP_M_P+0.5, med_IOLP_M_P, med_IOLP_M_P-0.5,med_IOLP_M_P-1) table_M_P[1:5, 2] <- M_P_list table_M_P[1:5, 3] <- refraction( IOL_power = table_M_P[1:5, 2], K1 = table_M_P[1:5, 5], K2 = table_M_P[1:5, 6], ELP = table_M_P[1:5, 9], AL = table_M_P[1:5, 4])}else{ IOLP_M_P_ref <- IOL_power_ref( ref = input$ref, K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_P, AL = input$AL ) med_IOLP_M_P <- as.numeric((round(IOLP_M_P_ref/0.5))*0.5) M_P_list <- c(med_IOLP_M_P +1, med_IOLP_M_P+0.5, med_IOLP_M_P, med_IOLP_M_P-0.5,med_IOLP_M_P-1) table_M_P[1:5, 2] <- M_P_list table_M_P[1:5, 3] <- refraction( IOL_power = table_M_P[1:5, 2], K1 = table_M_P[1:5, 5], K2 = table_M_P[1:5, 6], ELP = table_M_P[1:5, 9], AL = table_M_P[1:5, 4])} tableM_P <- table_M_P tableM_P <- tableM_P[, 2:3] tableM_P_15 <- tableM_P tableM_P_15$`Refraction at 15y` <- refraction( IOL_power = tableM_P_15[,1], K1 = input$K1, K2 = input$K2, ELP = values$ELP_M_P, AL = AL_15) tableM_P <- as.data.frame(tableM_P) tableM_P[, 1] <- round(tableM_P[, 1], 2) tableM_P[, 2] <- round(tableM_P[, 2], 2) tableM_P_15 <- as.data.frame(tableM_P_15) tableM_P_15[,1] <- round(tableM_P_15[,1],2) tableM_P_15[,2]<- round(tableM_P_15[,2],2) tableM_P_15[,3]<- round(tableM_P_15[,3],2) table_C_S <- data.frame(x = c(NA, NA, NA, NA, NA, NA), y = NA, z = NA, d = NA, e = NA, f = NA, g =NA, t = NA, n = NA) colnames(table_C_S) <- c("IOL", "IOL Power", "Refraction", "AL", "K1", "K2", "WTW", "Gender", "ELP") table_C_S$IOL <- "SN60AT/SN60WT" table_C_S$AL <- input$AL table_C_S$K1 <- input$K1 table_C_S$K2 <- input$K2 table_C_S$WTW <- input$WTW table_C_S$Gender <- input$Gender table_C_S$ELP <- values$ELP_C_S IOLPref0_C_S <- IOL_power_ref_0(AL = input$AL, K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_S) table_C_S[6, 2] <- IOLPref0_C_S table_C_S[6, 3] <- 0 if(input$ref == 0){ med_IOLP_C_S <- as.numeric((round(IOLPref0_C_S/0.5))*0.5) C_S_list <- c(med_IOLP_C_S +1, med_IOLP_C_S+0.5, med_IOLP_C_S, med_IOLP_C_S-0.5,med_IOLP_C_S-1) table_C_S[1:5, 2] <- C_S_list table_C_S[1:5, 3] <- refraction( IOL_power = table_C_S[1:5, 2], K1 = table_C_S[1:5, 5], K2 = table_C_S[1:5, 6], ELP = table_C_S[1:5, 9], AL = table_C_S[1:5, 4])}else{ IOLP_C_S_ref <- IOL_power_ref( ref = input$ref, K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_S, AL = input$AL ) med_IOLP_C_S <- as.numeric((round(IOLP_C_S_ref/0.5))*0.5) C_S_list <- c(med_IOLP_C_S +1, med_IOLP_C_S+0.5, med_IOLP_C_S, med_IOLP_C_S-0.5,med_IOLP_C_S-1) table_C_S[1:5, 2] <- C_S_list table_C_S[1:5, 3] <- refraction( IOL_power = table_C_S[1:5, 2], K1 = table_C_S[1:5, 5], K2 = table_C_S[1:5, 6], ELP = table_C_S[1:5, 9], AL = table_C_S[1:5, 4])} tableC_S <- table_C_S tableC_S <- tableC_S[, 2:3] tableC_S_15 <- tableC_S tableC_S_15$`Refraction at 15y` <- refraction( IOL_power = tableC_S_15[,1], K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_S, AL = AL_15) tableC_S <- as.data.frame(tableC_S) tableC_S[, 1] <- round(tableC_S[, 1], 2) tableC_S[, 2] <- round(tableC_S[, 2], 2) tableC_S_15 <- as.data.frame(tableC_S_15) tableC_S_15[,1] <- round(tableC_S_15[,1],2) tableC_S_15[,2]<- round(tableC_S_15[,2],2) tableC_S_15[,3]<- round(tableC_S_15[,3],2) table_C_P <- data.frame(x = c(NA, NA, NA, NA, NA, NA), y = NA, z = NA, d = NA, e = NA, f = NA, g =NA, t = NA, n = NA) colnames(table_C_P) <- c("IOL", "IOL Power", "Refraction", "AL", "K1", "K2", "WTW", "Gender", "ELP") table_C_P$IOL <- "SN60AT/SN60WT" table_C_P$AL <- input$AL table_C_P$K1 <- input$K1 table_C_P$K2 <- input$K2 table_C_P$WTW <- input$WTW table_C_P$Gender <- input$Gender table_C_P$ELP <- values$ELP_C_P IOLPref0_C_P <- IOL_power_ref_0(AL = input$AL, K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_P) table_C_P[6, 2] <- IOLPref0_C_P table_C_P[6, 3] <- 0 if(input$ref == 0){ med_IOLP_C_P <- as.numeric((round(IOLPref0_C_P/0.5))*0.5) C_P_list <- c(med_IOLP_C_P +1, med_IOLP_C_P+0.5, med_IOLP_C_P, med_IOLP_C_P-0.5,med_IOLP_C_P-1) table_C_P[1:5, 2] <- C_P_list table_C_P[1:5, 3] <- refraction( IOL_power = table_C_P[1:5, 2], K1 = table_C_P[1:5, 5], K2 = table_C_P[1:5, 6], ELP = table_C_P[1:5, 9], AL = table_C_P[1:5, 4])}else{ IOLP_C_P_ref <- IOL_power_ref( ref = input$ref, K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_P, AL = input$AL ) med_IOLP_C_P <- as.numeric((round(IOLP_C_P_ref/0.5))*0.5) C_P_list <- c(med_IOLP_C_P +1, med_IOLP_C_P+0.5, med_IOLP_C_P, med_IOLP_C_P-0.5,med_IOLP_C_P-1) table_C_P[1:5, 2] <- C_P_list table_C_P[1:5, 3] <- refraction( IOL_power = table_C_P[1:5, 2], K1 = table_C_P[1:5, 5], K2 = table_C_P[1:5, 6], ELP = table_C_P[1:5, 9], AL = table_C_P[1:5, 4])} tableC_P <- table_C_P tableC_P <- tableC_P[, 2:3] tableC_P_15 <- tableC_P tableC_P_15$`Refraction at 15y` <- refraction( IOL_power = tableC_P_15[,1], K1 = input$K1, K2 = input$K2, ELP = values$ELP_C_P, AL = AL_15) tableC_P <- as.data.frame(tableC_P) tableC_P[, 1] <- round(tableC_P[, 1], 2) tableC_P[, 2] <- round(tableC_P[, 2], 2) tableC_P_15 <- as.data.frame(tableC_P_15) tableC_P_15[,1] <- round(tableC_P_15[,1],2) tableC_P_15[,2]<- round(tableC_P_15[,2],2) tableC_P_15[,3]<- round(tableC_P_15[,3],2) table_R <- data.frame(x = c(NA, NA, NA, NA, NA, NA), y = NA, z = NA, d = NA, e = NA, f = NA, g =NA, t = NA, n = NA) colnames(table_R) <- c("IOL", "IOL Power", "Refraction", "AL", "K1", "K2", "WTW", "Gender", "ALP_O") table_R$IOL <- "SN60AT/SN60WT" table_R$AL <- input$AL table_R$K1 <- input$K1 table_R$K2 <- input$K2 table_R$WTW <- input$WTW table_R$Gender <- input$Gender table_R$ALP_O <- values$AL_optimized IOLPref0_R <- IOL_power_ref_0_T2(AL = input$AL, K1 = input$K1, K2 = input$K2, AL_O = values$AL_optimized, A = 118.3) table_R[6, 2] <- IOLPref0_R table_R[6, 3] <- 0 if(input$ref == 0){ med_IOLP_R <- as.numeric((round(IOLPref0_R/0.5))*0.5) R_list <- c(med_IOLP_R +1, med_IOLP_R+0.5, med_IOLP_R, med_IOLP_R-0.5,med_IOLP_R-1) table_R[1:5, 2] <- R_list table_R[1:5, 3] <- refraction_T2( IOL_power = table_R[1:5, 2], K1 = table_R[1:5, 5], K2 = table_R[1:5, 6], AL_O = table_R[1:5, 9], AL = table_R[1:5, 4], A = 118.3)}else{ IOLP_R_ref <- IOL_power_ref_T2( ref = input$ref, K1 = input$K1, K2 = input$K2, AL_O = values$AL_optimized, AL = input$AL, A = 118.3 ) med_IOLP_R <- as.numeric((round(IOLP_R_ref/0.5))*0.5) R_list <- c(med_IOLP_R +1, med_IOLP_R+0.5, med_IOLP_R, med_IOLP_R-0.5,med_IOLP_R-1) table_R[1:5, 2] <- R_list table_R[1:5, 3] <- refraction_T2( IOL_power = table_R[1:5, 2], K1 = table_R[1:5, 5], K2 = table_R[1:5, 6], AL_O = table_R[1:5, 9], AL = table_R[1:5, 4], A = 118.3) } tableR <- table_R tableR <- tableR[, 2:3] tableR_15 <- tableR tableR_15$`Refraction at 15y` <- refraction_T2( IOL_power = tableR_15[,1], K1 = input$K1, K2 = input$K2, AL_O = AL_optimized_15, AL = AL_15, A = 118.3) tableR <- as.data.frame(tableR) tableR[, 1] <- round(tableR[, 1], 2) tableR[, 2] <- round(tableR[, 2], 2) tableR_15 <- as.data.frame(tableR_15) tableR_15[,1] <- round(tableR_15[,1],2) tableR_15[,2]<- round(tableR_15[,2],2) tableR_15[,3]<- round(tableR_15[,3],2) table <- if(aa > 15){if(input$procedure == "MCTR" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableM_P } else if(input$procedure == "MCTR" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableM_S } else if(input$procedure == "CTR-CH" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableC_P } else if(input$procedure == "CTR-CH" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableC_S } else if(input$procedure == "SF-IOL" & input$IOL_type == "Rayner 920H/970C"){ table <- tableR }}else{ if(clus %in% c("C", "D")){ if(input$procedure == "MCTR" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableM_P } else if(input$procedure == "MCTR" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableM_S } else if(input$procedure == "CTR-CH" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableC_P } else if(input$procedure == "CTR-CH" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableC_S } else if(input$procedure == "SF-IOL" & input$IOL_type == "Rayner 920H/970C"){ table <- tableR } }else{ if(input$procedure == "MCTR" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableM_P_15 } else if(input$procedure == "MCTR" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableM_S_15 } else if(input$procedure == "CTR-CH" & input$IOL_type == "DCB00/ICB00/ZCB00"){ table <- tableC_P_15 } else if(input$procedure == "CTR-CH" & input$IOL_type == "SN60AT/SN60WF"){ table <- tableC_S_15 } else if(input$procedure == "SF-IOL" & input$IOL_type == "Rayner 920H/970C"){ table <- tableR_15 } } } table datatable(table, selection = 'none') %>% formatStyle( columns = 1:ncol(table), # 应用到所有列 valueColumns = NULL, # 或者指定单列:比如 c('column_name') target = 'row', backgroundColor = styleEqual(3, '#D3D3D3')# 第三行的背景颜色加深 )%>% formatStyle( columns = 1:ncol(table), # 应用到所有列 valueColumns = NULL, # 或者指定单列:比如 c('column_name') target = 'row', backgroundColor = styleEqual(6, '#D3D3D3')# 第三行的背景颜色加深 ) # 返回处理和格式化后的 data.frame,以便用于渲染或传递 datatable(table, selection = 'none') }) #A = 118.3 IOL_types <- eventReactive(input$cal, { IOL_types <- c("PCB00/ZCB00","SN60AT/SN60WF") }) words_M_P_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("MCTR","
", "
", "IOL: ", "PCB00/ZCB00", "
", "
", "Patient: ", input$name, "
", "
", "DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Doctor: ", input$surger, "
", "
", "Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) words_M_S_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("MCTR","
", "
", "IOL: ", "SN60AT/SN60WF", "
", "
", "Patient: ", input$name, "
", "
", "DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Doctor: ", input$surger, "
", "
", "Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) words_C_P_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("CTR-CH","
", "
", "IOL: ", "PCB00/ZCB00", "
", "
", "Patient: ", input$name, "
", "
", "DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Doctor: ", input$surger, "
", "
", "Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) words_C_S_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("CTR-CH","
", "
", "IOL: ", "SN60AT/SN60WF", "
", "
", "Patient: ", input$name, "
", "
", "DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Doctor: ", input$surger, "
", "
", "Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) words_R_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("SF-IOL","
", "
", "IOL: ", "SN60AT/SN60WF", "
", "
", "Patient: ", input$name, "
", "
", "DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Doctor: ", input$surger, "
", "
", "Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) word_val <- eventReactive(input$cal, { # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("Patient: ", input$name, " ","DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Procedure:",input$procedure," ", "IOL: ", input$IOL_type, "
", "
", "Doctor: ", input$surger, " ","Surgery Date: ", format(input$Sob, "%Y-%m-%d"))) }) word_val_15 <- eventReactive(input$cal, { values <- calculateValues() aa <- values$aa clus <- values$clus if(aa <= 15){ if(clus == "A"){ AL_15 <- 1.67 * log10(aa +0.6) +21.71 }else{ if(clus == "B"){ AL_15 <- 7.2 * log10(aa +0.6) +19.69 }else{ AL_15 <- input$AL } } }else( AL_15 <- input$AL ) AL_15 <- round(AL_15, 2) # 构建 words_P 字符串或者 HTML 内容 HTML(paste0("Patient: ", input$name, " ","DOB: ", format(input$dob, "%Y-%m-%d"), "
", "
", "Procedure:",input$procedure," ", "IOL: ", input$IOL_type, "
", "
", "Doctor: ", input$surger, " ","Surgery Date: ", format(input$Sob, "%Y-%m-%d"),"
", "
", "The patient is expected to have AL of ", AL_15, "mm at the age of 15")) }) #words_M_P,words_M_S,words_C_P, words_C_S, words_R output$table <- renderDataTable({ table_reactive() }) word_val_ff <- eventReactive(input$cal, { today <- Sys.Date() dob <- as.Date(input$dob) surgery_date <- as.Date(input$Sob) aa <- as.numeric(difftime(surgery_date, dob, units = "days")) / 365.25 values <- calculateValues() clus <- values$clus if(clus == "A") { C_ph <- 0 } else { if(clus %in% c("C","D")){ C_ph <- 3 }else{ C_ph <- 1 }} if( aa >15 ){ word_val() }else{ if(C_ph == 3){ word_val() }else{ word_val_15() } } }) output$words <- renderUI({ word_val_ff() }) output$conditional_layout <- renderUI({ values <- calculateValues() aa <- values$aa clus <- values$clus if (aa > 15 || clus %in% c("C", "D")) { div( style = "width: 100%; max-width: 1300px; margin: 0 auto;", # 外层容器最大1300px card( style = "width: 100%; max-width: 1300px; margin: 0 auto;", # card充满容器 fluidRow( div( style = "width: 600px; margin: 0 auto;", # 固定内容宽度600px uiOutput("words") ) ), fluidRow( div( style = "width: 600px; margin: 0 auto;", # 固定内容宽度600px DTOutput("table") ) ) ) ) } else { div( style = "width: 100%; max-width: 1300px; margin: 0 auto; margin-top: 20px;", card( fluidRow( div( style = "width: 600px; margin: 0 auto;", uiOutput("words") ) ), fluidRow( column( width = 6, div( style = "width: 550px;", # 表格区域固定宽度 DTOutput("table") ) ), column( width = 6, imageOutput("cluster_image") # 动态显示图片 ) ) ) ) } }) output$cluster_image <- renderImage({ list( src = rdata_file3, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$words_cluster <- renderUI({ clus <- calculateValues()$clus description <- switch(clus, "A" = "
Cluster A: Pediatric Patients with Ectopia Lentis and Minimal Other Ocular Features of Marfan Syndrome. This subtype primarily includes children under 12 years of age whose axial length (AL) is generally within the normal range for age. Some patients may exhibit mildly elongated AL but lack other characteristic features such as corneal flattening or thinning. Postoperative visual recovery in this group tends to be faster compared to Type B patients. The incidence of posterior capsular opacification (PCO) is similar to that of Type B, with approximately 30% requiring Nd:YAG laser treatment within two years after surgery.
", "B" = "
Cluster B: Pediatric Patients with Ectopia Lentis, Long Axial Length, Flat Cornea, and Thin Cornea. Also primarily involving children under 12 years, this subtype is characterized by significantly elongated AL compared to age-matched norms. Some patients may present with normal AL but exhibit other features such as a flatter and thinner cornea. Compared to Type A, visual recovery is slower in this group, while the incidence of PCO remains comparable, with about 30% of patients requiring laser capsulotomy within two years postoperatively.
", "C" = "
Cluster C: Adolescent and Adult Patients with Ectopia Lentis and Normal to Moderately Long Axial Length. This group includes patients aged 12 years and older, with axial lengths typically not exceeding 28 mm. Postoperative visual recovery in this subtype is the most rapid among all clusters, and the incidence of PCO is the lowest, with only approximately 13% of patients requiring laser treatment within two years after surgery.
", "D" = "
Cluster D: Patients with Ectopia Lentis and Markedly Elongated Axial Length. This subtype includes adults with AL greater than 28 mm and children whose AL is substantially longer than age-matched peers. These patients show the slowest postoperative visual improvement and the highest risk of PCO, with approximately 45% requiring Nd:YAG laser capsulotomy within two years postoperatively.
", "
No cluster information available.
" ) HTML(description) }) # PCO_sur 输出逻辑 output$PCO_sur <- -renderImage({ list( src = rdata_file1, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$img1_ui <-renderImage({ list( src = rdata_file2, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) } shinyApp(ui = ui, server = server) ``` ```{shinylive-r} #| standalone: true #| viewerHeight: 200 library(shiny) library(ggplot2) library(shinyjs) ui <- fluidPage( useShinyjs(), actionButton("cal", "Estimate IOL Power"), imageOutput("img1_ui"), imageOutput("img2_ui"), imageOutput("img3_ui"), uiOutput("words") ) server <- function(input, output, session) { rdata_file1 <- tempfile(fileext = ".png") correct_url1 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup1.png" download.file(correct_url1, destfile = rdata_file1, mode = "wb") rdata_file2 <- tempfile(fileext = ".png") correct_url2 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/Logo-Department.png" download.file(correct_url2, destfile = rdata_file2, mode = "wb") rdata_file3 <- tempfile(fileext = ".png") correct_url3 <- "https://raw.githubusercontent.com/XinshenFD/data-save/main/sup2.png" download.file(correct_url3, destfile = rdata_file3, mode = "wb") output$img1_ui <- renderImage({ list( src = rdata_file1, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$img2_ui <- renderImage({ list( src = rdata_file2, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) output$img3_ui <- renderImage({ list( src = rdata_file3, contentType = "image/png", style = "width:100%; height:auto;" ) }, deleteFile = FALSE) observeEvent(input$cal, { shinyjs::show("img1_ui") output$words <- renderUI({ HTML("Calculation completed!") }) }) } shinyApp(ui = ui, server = server) ```