You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R Shiny中shinyMatrix多矩阵单向值联动异常如何修复?

R Shiny矩阵联动问题修复方案

核心原因

你定义的curveRate函数硬编码了生成矩阵的行数为1,当用户在2号矩阵curveBaseRate中新增行后,传入该函数的X、Y值都是长度大于1的向量,强制按1行构造会导致矩阵结构错乱,就是你看到的渲染异常问题。

修改步骤

只需要调整2处代码即可修复:

  1. 重构curveRate函数的矩阵构造逻辑,根据传入的X列向量长度动态设置行数,不要写死为1
  2. 在唤起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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:36:03