简体   繁体   English

在 R shiny 中,如何为反应式 object 渲染 plot?

[英]In R shiny, how do you render a plot for a reactive object?

I've rendered plenty of plots in Shiny but this one is throwing me.我在 Shiny 中绘制了很多图,但这个让我很困惑。 When running the below MWE code, the default data.table is properly rendered in the main panel under the "Liabilities Module" tab.运行以下 MWE 代码时,默认的 data.table 会正确呈现在“负债模块”选项卡下的主面板中。 This data.table is the default view when first opening this tab.这个 data.table 是第一次打开这个标签时的默认视图。 See first image below to see what this looks like.请参阅下面的第一张图片以了解它的外观。

However, when I click on the "Vector plots" action button in that same "Liabilities Module" main panel, I get Error: need finite 'ylim' values as shown in the 2nd image below.但是,当我在同一个“负债模块”主面板中单击“矢量图”操作按钮时,出现错误:需要有限的“ylim”值,如下面的第二张图片所示。

The reactive object for rendering the data.table (which works as intended) and the plot (which doesn't work) is the same - vectorsAll .用于呈现 data.table(按预期工作)和 plot(不工作)的反应式 object 是相同的 - vectorsAll

How do I plot the vectorsAll object?我如何将vectorsAll object? So that when the user clicks the "Vector plots" action button without having first clicked on the "Input Liabilities" action button in the sidebar panel, that same data from the default table is now plotted (value of 0.2 for 60 periods)?因此,当用户单击“矢量图”操作按钮而没有先单击侧边栏面板中的“输入负债”操作按钮时,现在会绘制默认表中的相同数据(60 个周期的值为 0.2)? Also, when the user clicks on the "Input Liabilities" action button and changes the value in row A of the matrix input grid, both the data.table and plot should update accordingly (the correct updating of the data.table based on the user changing the row A input matrix from 0.2 to 0.23 is shown in the 3rd image below).此外,当用户单击“输入负债”操作按钮并更改矩阵输入网格 A 行中的值时,data.table 和 plot 都应相应更新(根据用户更改 A 行正确更新 data.table从 0.2 到 0.23 的输入矩阵如下面的第三张图所示)。

I'd like to keep this in native Shiny, no ggplot or other plot package. I'll make this App fancier later as it progresses.我想将其保留在本机 Shiny 中,而不是 ggplot 或其他 plot package。随着它的进步,我会在稍后让这个应用程序更有趣。

MWE code: 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")}

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)}

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),
        tabPanel("By accounts", value=3), 
        tabPanel("Liabilities module", value=4,
                 fluidRow(h5(strong(helpText("Select model output to view:")))),
                 fluidRow(
                   button2('showVectorValueBtn','Vector values'),
                   button2('showVectorPlotBtn','Vector plots'),
                 ), # close fluid row
                 
                 div(style = "margin-top: 5px"),
                 
                 # Shows outputs on each page of main panel   
                 uiOutput('showResults')), 
        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==4",
        actionButton('showLiabilityGrid','Input Liabilities',style='width:100%;background-color:LightGrey'),
        setShadow(id='showLiabilityGrid'),
        div(style = "margin-bottom: 10px"),
      ), # close conditional panel
      conditionalPanel(condition="input.tabselected==3"),
      conditionalPanel(condition="input.tabselected==4")
    ) # close tagList
  }) # close renderUI
  
  # --- Below defines the vectorsAll object before user clicks on actionButton "Input Liabilities" ---->
  vectorsAll <- reactive({
    if (is.null(input$showLiabilityGrid)){df <- NULL}
    else {
      if(input$showLiabilityGrid < 1){df <- cbind(Period = 1:60,Yld_Rate = pct(0.2))}  # define what you want to display by default
      else {
        req(input$base_input)
        df <- cbind(Period = 1:60,Yld_Rate = pct(yield()[,2]))
      } # close 2nd else
    } # close 1st else
    df
  }) # close reactive
  
  output$table1 <- renderTable({vectorsAll()})
  
  # --- Below produces vector values after clicking "Vector Values" button; see above for pre-click ---->
  observeEvent(input$showVectorValueBtn,
               {showResults$showme <-
                 tagList(tableOutput("table1"))
               },ignoreNULL = FALSE)
  
  # --- Below produces vector plots -------------------------------------------------------------------->   
  output$graph1 <-renderPlot(plot(vectorsAll()))
  observeEvent(input$showVectorPlotBtn,{showResults$showme <- plotOutput("graph1")})
  
  # --- Below sends both vector plots and vector values to UI section above ---------------------------->
  output$showResults <- renderUI({showResults$showme})
  
  # --- Below for modal dialog inputs ------------------------------------------------------------------>
  observeEvent(input$showLiabilityGrid,
               {showModal(modalDialog(
                 matrix1Input("base_input"),
                 div(style = "margin-top: 0px"),
                 useShinyjs(),
               ) # close modalDialog
               ) # close showModal
               } # close showModal function
  ) # close observeEvent
  
}) # close server

shinyApp(ui, server)

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

Your variable/column Yld_Rate is character with % in it.您的变量/列Yld_Rate是其中包含%的字符。 Once you substitute it to a missing value, it works fine.一旦将其替换为缺失值,它就可以正常工作。 Try this尝试这个

output$graph1 <-renderPlot(plot(sapply(vectorsAll(), function(x)gsub("%", "", x))))

输出

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

相关问题 你如何使用无功输入作为 Shiny 中 plot 的轴之一 - How do you use the reactive input as one of the axis of a plot in Shiny 在 R Shiny 中,如何将用户从 UI 中选择的输入粘贴到服务器中的反应式 object 中? - In R Shiny, how do you paste a user's selected input from UI into a reactive object in server? 在 R shiny 中如何呈现一个反应式 data.table? - In R shiny how to render a reactive data table? R闪亮的反应式表格,渲染图无法正常工作 - R shiny reactive table, render plot can not work 点击事件和渲染图之间的R Shiny Reactive无限循环 - R Shiny Reactive infinite loop between click event and render plot 如何在 R Shiny 应用程序中创建具有两个反应值的堆积百分比条形图? - How do you create a stacked percentage bar chart in R Shiny app with two reactive values? 如何避免仍将在 shiny 中创建的反应式 object 的 output(渲染)错误? - How to avoid error in the output (render) of a reactive object that will still be created in shiny? R shiny 无法呈现 plot - R shiny unable to render the plot 如何在 Shiny 应用程序中使用 ggplot 创建反应图 - How do I create a reactive plot using ggplot in Shiny application R:In Shiny如何修复应用于“反应性”类对象的“xtable”的适用方法 - R: In Shiny how do I fix no applicable method for 'xtable' applied to an object of class “reactive”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM