简体   繁体   English

在 R shiny 中如何呈现一个反应式 data.table?

[英]In R shiny how to render a reactive data table?

The below MWE code works as intended, except that the data.table output is not being rendered in the main panel when the "Vector values" action button is clicked in the "By balances" tab (first tab that appears by default).以下 MWE 代码按预期工作,除了在“按余额”选项卡(默认显示的第一个选项卡)中单击“矢量值”操作按钮时,主面板中未呈现 data.table output。

For now I'd like to render the table in base Shiny without using a table package such as DT.现在,我想在不使用表 package(例如 DT)的情况下在基数 Shiny 中呈现表。

I don´t think the vectorsAll function below is necessary, I've tried this with yield() function instead and it still doesn't work.我不认为下面的vectorsAll function 是必要的,我已经用yield() function 试过了,但它仍然不起作用。

What am I doing wrong?我究竟做错了什么? This should be such a simple thing, rendering a 60 row data.table, I'm sure I'm overlooking something very obvious.这应该是一件很简单的事情,渲染 60 行 data.table,我确定我忽略了一些非常明显的东西。

vectorPlot function that goes with below MWE:与以下 MWE 一起使用的 vectorPlot function:

vectorPlot <- function(w,x,y,z){plot(w,main=x,xlab=y,ylab=z,type="b",col="blue",pch=19,cex=1.25)}

MWE: MWE:

library(shiny)
library(shinyMatrix)
library(shinyjs)

button2 <- function(x,y){actionButton(x,y,style="width:90px;margin-bottom:5px;font-size:80%")}

matrix1Input <- function(x){
  matrixInput(x, 
              value = matrix(c(0.2), 4, 1, dimnames = list(c("A","B","C","D"),NULL)),
              rows = list(extend = FALSE,  names = TRUE),
              cols = list(extend = FALSE, names = FALSE, editableNames = FALSE),
              class = "numeric")}

vectorBase <- function(x,y){
  a <- rep(y,x)
  b <- seq(1:x)
  c <- data.frame(x = b, y = a)
  return(c)}

ui <- 
  pageWithSidebar(
    headerPanel("Model..."),
    sidebarPanel(
      fluidRow(helpText(h5(strong("Base Input Panel")),align="center",
                        style="margin-top:-15px;margin-bottom:5px")),
    # Panels rendered with uiOuput & renderUI in server to stop flashing at invocation
      uiOutput("Panels") 
    ), # close sidebar panel
    mainPanel(
      tabsetPanel(
        tabPanel("By balances", value=2,
                 fluidRow(h5(strong(helpText("Select model output to view:")))),
                 fluidRow(
                   button2('showVectorPlotBtn','Vector plots'),
                   button2('showVectorValueBtn','Vector values'),
                 ), # close fluid row
                 
                 div(style = "margin-top: 5px"),
                
                 # Shows outputs on each page of main panel   
                 uiOutput('showResults'),
        ),  # close tab panel
        tabPanel("By accounts", value=3), 
        tabPanel("Liabilities module", value=4), 
        id = "tabselected"
      ) # close tabset panel
    ) # close main panel
  ) # close page with sidebar

server <- function(input,output,session)({
  
  base_input  <- reactive(input$base_input)
  showResults <- reactiveValues()

  yield   <- function(){vectorBase(60,input$base_input[1,1])} # Must remain in server section
  
  # --- Conditional panels rendered here rather than in UI to eliminate invocation flashing ---------->
  output$Panels <- renderUI({
    tagList( 
      conditionalPanel(
        condition="input.tabselected==2",
        matrix1Input("base_input"),
        div(style = "margin-top: 0px"), 
        useShinyjs(),
      ), # close conditional panel
      conditionalPanel(condition="input.tabselected==3"),
      conditionalPanel(condition="input.tabselected==4")
    ) # close tagList
  }) # close renderUI
  
  # --- Below produces vector plots as default view when first invoking App ----------------------------->
  output$graph1 <-renderPlot(vectorPlot(yield(),"A Variable","Period","Rate"))
  
  # --- Below produces vector plots after having clicked "Vector Plot" button; see above for pre-click ->
  observeEvent(input$showVectorPlotBtn,
               {showResults$showme <- 
                 tagList(plotOutput("graph1"))
               },ignoreNULL = FALSE)
  
  # --- Below produces vector values table ------------------------------------------------------------->
  vectorsAll <- reactive({cbind(Period = 1:60,Yld_Rate = pct(yield()[,2]))})
  
  output$table1 <- renderTable({vectorsAll()})
  
  observeEvent(input$showVectorValueBtn,{showResults$showme <- show("table1")})

  # --- Below sends both vector plots and vector values to UI section above ---------------------------->
  output$showResults <- renderUI({showResults$showme})

}) # close server

shinyApp(ui, server)

Mistake was to use show("table1") instead of tableOutput("table1") in the last observeEvent in the original MWE code posted above.错误是在上面发布的原始 MWE 代码中的最后一个observeEvent中使用show("table1")而不是tableOutput("table1") Also two custom functions in the original MWE were erroneously omitted: "pct" and "vectorPlot".原始 MWE 中的两个自定义函数也被错误地省略了:“pct”和“vectorPlot”。 Revised MWE code below now uses the correct table output syntax and includes all required functions.下面修改后的 MWE 代码现在使用正确的表 output 语法并包括所有必需的函数。 Now it runs as intended.现在它按预期运行。 Thanks to YBS comment for pointing out the error.感谢 YBS comment 指出错误。

library(shiny)
library(shinyMatrix)
library(shinyjs)

button2 <- function(x,y){actionButton(x,y,style="width:90px;margin-bottom:5px;font-size:80%")}

matrix1Input <- function(x){
  matrixInput(x, 
              value = matrix(c(0.2), 4, 1, dimnames = list(c("A","B","C","D"),NULL)),
              rows = list(extend = FALSE,  names = TRUE),
              cols = list(extend = FALSE, names = FALSE, editableNames = FALSE),
              class = "numeric")}

pct <- function(x){paste(format(round(x*100,digits=1),nsmall=1),"%",sep="")} # convert to percentage

vectorBase <- function(x,y){
  a <- rep(y,x)
  b <- seq(1:x)
  c <- data.frame(x = b, y = a)
  return(c)}

vectorPlot <- function(w,x,y,z){plot(w,main=x,xlab=y,ylab=z,type="b",col="blue",pch=19,cex=1.25)}

ui <- 
  pageWithSidebar(
    headerPanel("Model..."),
    sidebarPanel(
      fluidRow(helpText(h5(strong("Base Input Panel")),align="center",
                        style="margin-top:-15px;margin-bottom:5px")),
    # Panels rendered with uiOuput & renderUI in server to stop flashing at invocation
      uiOutput("Panels") 
    ), # close sidebar panel
    mainPanel(
      tabsetPanel(
        tabPanel("By balances", value=2,
                 fluidRow(h5(strong(helpText("Select model output to view:")))),
                 fluidRow(
                   button2('showVectorPlotBtn','Vector plots'),
                   button2('showVectorValueBtn','Vector values'),
                 ), # close fluid row
                 
                 div(style = "margin-top: 5px"),
                
                 # Shows outputs on each page of main panel   
                 uiOutput('showResults'),
        ),  # close tab panel
        tabPanel("By accounts", value=3), 
        tabPanel("Liabilities module", value=4), 
        id = "tabselected"
      ) # close tabset panel
    ) # close main panel
  ) # close page with sidebar

server <- function(input,output,session)({
  
  base_input  <- reactive(input$base_input)
  showResults <- reactiveValues()

  yield   <- function(){vectorBase(60,input$base_input[1,1])} # Must remain in server section
  
  # --- Conditional panels rendered here rather than in UI to eliminate invocation flashing ---------->
  output$Panels <- renderUI({
    tagList( 
      conditionalPanel(
        condition="input.tabselected==2",
        matrix1Input("base_input"),
        div(style = "margin-top: 0px"), 
        useShinyjs(),
      ), # close conditional panel
      conditionalPanel(condition="input.tabselected==3"),
      conditionalPanel(condition="input.tabselected==4")
    ) # close tagList
  }) # close renderUI
  
  # --- Below produces vector plots as default view when first invoking App ----------------------------->
  output$graph1 <-renderPlot(vectorPlot(yield(),"A Variable","Period","Rate"))
  
  # --- Below produces vector plots after having clicked "Vector Plot" button; see above for pre-click ->
  observeEvent(input$showVectorPlotBtn,
               {showResults$showme <- 
                 tagList(plotOutput("graph1"))
               },ignoreNULL = FALSE)
  
  # --- Below produces vector values table ------------------------------------------------------------->
  vectorsAll <- reactive({cbind(Period = 1:60,Yld_Rate = pct(yield()[,2]))})
  
  output$table1 <- renderTable({vectorsAll()})
  
  observeEvent(input$showVectorValueBtn,{showResults$showme <- tableOutput("table1")})
  
  # --- Below sends both vector plots and vector values to UI section above ---------------------------->
  output$showResults <- renderUI({showResults$showme})

}) # close server

shinyApp(ui, server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM