R Shiny App首次启动时如何实现侧边栏默认表格正常渲染?
问题解决方案
错误根源
报错核心原因是首次启动App时input$matrix3未初始化:矩阵输入组件封装在reactiveValues中,只有点击Modify弹出模态框后才会渲染到页面,Shiny才会生成对应的input值。首次渲染表格时input$matrix3为NULL,调用矩阵相关操作函数自然抛出is.matrix(value) is not TRUE错误。
修正后完整代码
library(shiny) library(shinyMatrix) library(shinyjs) # 给矩阵网格分配行标题 matrix3Headers <- function(){c('A','B','C','D')} # 给矩阵网格第一列分配默认值 matrix3Default <- matrix(c(1,24,0,100),4,1,dimnames=list(matrix3Headers(),NULL)) colnames(matrix3Default) <- paste0("Series ",1:ncol(matrix3Default)) # 矩阵输入组件生成函数 matrix3Input <- function(x, matrix3Default){ matrixInput(x, label = '在下方网格输入序列参数:', value = matrix3Default, rows = list(extend=FALSE,names=TRUE), cols = list(extend=TRUE,names=TRUE,editableNames=FALSE,delete=TRUE), class = 'numeric' ) } ui <- fluidPage( useShinyjs(), titlePanel('参数输入'), fluidRow(actionButton('modify','修改'),tableOutput('table2')) ) server <- function(input, output, session){ rv <- reactiveValues( mat3=matrix3Input('matrix3',matrix3Default), input=matrix3Default ) observeEvent(input$modify,{ # 每次打开模态框前更新矩阵输入的默认值为最新修改后的值 rv$mat3 <- matrix3Input('matrix3', rv$input) showModal(modalDialog( rv$mat3 )) }) output$table2 <- renderTable({ # 优先取用户修改后的矩阵值,不存在则用默认值 df <- if(is.null(input$matrix3)){ matrix3Default } else { input$matrix3 } n <- dim(df)[2] rownames(df) <- matrix3Headers() # 保存最新矩阵值到reactiveValues持久存储 rv$input <- df colnames(df) <- paste("序列", 1:n) df },rownames=TRUE, colnames=TRUE) } shinyApp(ui, server)
核心修改点
- 修正了原代码中
df >- NULL的语法错误,同时把首次启动的df取值从NULL改为默认矩阵matrix3Default,保证首次渲染表格时传入的是合法矩阵 - 把矩阵输入组件的更新逻辑从
renderTable迁移到observeEvent(input$modify)中,避免表格渲染时重复生成组件导致的响应冲突 - 调整取值逻辑:优先读取用户修改后的
input$matrix3,不存在(首次启动)时回退到默认矩阵
修改持久保留的实现原理
reactiveValues中存储的变量是Shiny会话级别的全局状态,只要不刷新页面、不结束会话,变量值就会一直保留- 每次用户在模态框的矩阵输入组件中修改内容,
input$matrix3会自动更新,触发renderTable重新执行,此时会把最新的矩阵值同步到rv$input中 - 每次点击Modify触发模态框弹出时,会用
rv$input中存储的最新值初始化矩阵输入组件,所以之前的修改不会丢失,可在多次打开模态框时复用。
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

