R Shiny中shinyMatrix多矩阵单向值联动异常如何修复?
R Shiny矩阵联动问题修复方案
核心原因
你定义的curveRate函数硬编码了生成矩阵的行数为1,当用户在2号矩阵curveBaseRate中新增行后,传入该函数的X、Y值都是长度大于1的向量,强制按1行构造会导致矩阵结构错乱,就是你看到的渲染异常问题。
修改步骤
只需要调整2处代码即可修复:
- 重构
curveRate函数的矩阵构造逻辑,根据传入的X列向量长度动态设置行数,不要写死为1 - 在唤起3号矩阵的监听事件中增加
req(input$curveBaseRate)校验,避免2号矩阵未初始化完成时点击按钮触发异常
修正后的完整代码
library(shiny);library(shinyMatrix);library(shinyjs) f <- function(action,i){as.character(checkboxInput(paste0(action,i),label=NULL))} actions <- c("show", "reset") tbl <- t(outer(actions, c(1,2), FUN = Vectorize(f))) colnames(tbl) <- c("Show", "Reset") rownames(tbl) <- c("Base", "Spread") xDflt <- .05 # << default value for x column of input matrix yDflt <- .01 # << default value for y column of input matrix flatRate <- function(inputId,x,y){ matrixInput(inputId, value = matrix(c(x,y), 1, 1, dimnames = list(c("Base rate"),NULL)), rows = list(extend = FALSE, names = TRUE), cols = list(extend = FALSE, names = FALSE, editableNames = FALSE), class = "numeric") } # 此处修改:动态设置矩阵行数,不再硬编码为1 curveRate <- function(inputId,w,x,y){ matrixInput(inputId, label = w, value = matrix(c(x,y), nrow = length(x), ncol = 2, dimnames=list(NULL,c("Period (X)","Curved (Y)"))), rows = list(extend = TRUE, names = FALSE), cols = list(extend = FALSE, names = TRUE, editableNames = FALSE), class = "numeric") } ui <- fluidPage( tags$head( tags$style(HTML( "td .checkbox {margin-top: 0; margin-bottom: 0;} td .form-group {margin-bottom: 0;}" )) ), titlePanel("Model"), sidebarLayout( sidebarPanel(uiOutput("Panel")), mainPanel(tabsetPanel(tabPanel("Rates", value=2),id = "tabselected")) ) ) server <- function(input,output,session)({ output$Panel <- renderUI({ conditionalPanel( condition = "input.tabselected == 2", useShinyjs(), helpText("Modeled periods (X):"), sliderInput('periods','',min=2,max=120,value=60), helpText("Initial rates (Y):"), flatRate("flatInput",xDflt,yDflt), helpText("Generate curves (Y|X):"), tableOutput("checkboxes"), hidden(uiOutput("curveBaseRate")), actionButton("addScenarios","Add scenarios") ) }) ### Begin checkbox matrix ### output[["checkboxes"]] <- renderTable({tbl}, rownames = TRUE, align = "c", sanitize.text.function = function(x) x ) observeEvent(input[["show1"]], { if(input[["show1"]]){ shinyjs::show("curveBaseRate") } else { shinyjs::hide("curveBaseRate") } }) ### End checkbox matrix ### output$curveBaseRate <- renderUI({ req(input$periods,input$flatInput) input[["reset1"]] curveRate("curveBaseRate", "Base rates curve (Y|X):", input$periods, input$flatInput[1,1]) }) outputOptions(output, "curveBaseRate", suspendWhenHidden = FALSE) # 此处修改:增加req校验确保2号矩阵已就绪 observeEvent(input$addScenarios, { req(input$curveBaseRate) showModal( modalDialog( curveRate("curveBaseRateAdd", "Base rates curve (Y|X):", input$curveBaseRate[,1], input$curveBaseRate[,2]), footer = modalButton("Close") )) }) }) shinyApp(ui, server)
补充说明
原来引用2号矩阵行列的写法input$curveBaseRate[,1]、input$curveBaseRate[,2]本身没有错误,只是构造矩阵时行数硬编码导致的结构不匹配。
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

