r - Ggplot2 在 Shiny 的应用程序中显示错误消息

标签 r ggplot2 shiny

请我尝试将我的 Shiny 应用程序中的图表转换为 ggplot2 图表。我使用 react 函数来生成财务比率的值,这些值绘制在条形图和饼图中,例如利润/营业额。当您加载应用程序时,默认情况下,每个输入字段(利润输入字段和营业额输入字段)包含值,其比率绘制在图表中。加载应用程序时将显示 ggplot2 图表。但是,当我清除输入字段(例如利润)以便我可以输入新值时,我在控制台中收到以下错误消息:

Warning in profit/turnover :

  longer object length is not a multiple of shorter object length

Warning: Error in data.frame: arguments imply differing number of rows: 5, 4

  131: stop

  130: data.frame

  129: <reactive:profitability.df> [C:\Users\Idiaye\Documents\R data\mavisanalytic/app.R#446]

  113: profitability.df

   99: renderPlotly [C:\Users\Idiaye\Documents\R data\mavisanalytic/app.R#451]

   98: func

   95: func

   82: origRenderFunc

   81: output$bar

    1: shiny::runApp

该应用程序旨在计算和绘制短短五年内的财务比率;因此,有五个数据输入字段,每个字段用于利润和营业额。尽管如此,我希望用户能够分析他们选择的任意年份的财务业绩。但是,当清除输入字段时,我收到上述错误消息。在将绘图转换为 ggplot2 之前,我没有遇到此问题。以下是我的可重现代码:

library(shiny)
library(ggplot2)
library(plotly)

ui<-navbarPage(
    windowTitle="Reprex",fluid=TRUE, title=strong("Reprex"),
    tabPanel(title="Reprex App",
        sidebarLayout(
            sidebarPanel(width=2,
                actionButton("delete",strong("Clear Fields"),icon=icon("broom")),br(),br(),  
                textInput("pro","Profit 1",value="100000",width=150),
                textInput("prof","Profit 2",value="150000",width=150),
                textInput("profs","Profit 3",value="200000",width=150),
                textInput("profit","Profit 4",value="250000",width=150),
                textInput("profits","Profit 5",value="300000",width=150),
                hr(),
                h4(strong("Turnover figures:")),
                actionButton("remove",strong("Clear Fields"),icon=icon("broom")),br(),br(),
                textInput("turn","Turnover 1",value="350000",width=150),
                textInput("turno","Turnover 2",value="300000",width=150),
                textInput("turnov","Turnover 3",value="420000",width=150),
                textInput("turnover","Turnover 4",value="600000",width=150),
                textInput("turnovers","Turnover 5",value="550000",width=150),
                actionButton("go",strong("Calculate Ratio"),icon=icon("caret-right"))
                
            ),mainPanel(
                plotlyOutput("plot")
            )
        )
    )
)

server<-function(input,output,session){
    
    observeEvent(input$delete,{
        
        updateTextInput(session,"pro",value="",placeholder="0")
        updateTextInput(session,"prof",value="",placeholder="0")
        updateTextInput(session,"profs",value="",placeholder="0")
        updateTextInput(session,"profit",value="",placeholder="0")
        updateTextInput(session,"profits",value="",placeholder="0")
    })
    
    
    observeEvent(input$remove,{
        
        updateTextInput(session,"turn",value="",placeholder="0")
        updateTextInput(session,"turno",value="",placeholder="0")
        updateTextInput(session,"turnov",value="",placeholder="0")
        updateTextInput(session,"turnover",value="",placeholder="0")
        updateTextInput(session,"turnovers",value="",placeholder="0")
    })
    
    profits<-reactive({
        as.numeric(c(
            if(input$pro>0){input$pro},
            if(input$prof>0){input$prof},
            if(input$profs>0){input$profs},
            if(input$profit>0){input$profit},
            if(input$profits>0){input$profits}
        ))
    })
    
    turnover<-reactive({
        as.numeric(c(
            if(input$turn>0){input$turn},
            if(input$turno>0){input$turno},
            if(input$turnov>0){input$turnov},
            if(input$turnover>0){input$turnover},
            if(input$turnovers>0){input$turnovers}
        ))
    })
    
    year<-reactive({
        c(
            if(input$pro>0){"Year 1"},
            if(input$prof>0){"Year 2"},
            if(input$profs>0){"Year 3"},
            if(input$profit>0){"Year 4"},
            if(input$profits>0){"Year 5"}
        )
    })
    profit.ratio<-function(profits,turnover){
        profitability<-round(profits/turnover*100,1)
        return(profitability)
    }
  profitability<-reactive({profit.ratio(profits(),turnover())}) 
  
  
  
  profit.df<-reactive({data.frame(profitability(),year())})
  
  output$plot<-renderPlotly({
      input$go
      isolate(profit.df()%>%
          ggplot()+aes(x=year(),y=profitability(),fill=year())+geom_bar(stat="identity")+
          labs(x="Years",y="Profitability ratios (%)",fill="Years")+scale_fill_brewer(palette="Set1")+
              geom_text(label=profitability(),position=position_stack(vjust=0.8)))
  })
}
shinyApp(ui=ui,server=server)

感谢您的建议。

最佳答案

您可以使用req来确保所有输入满足进一步处理所需的条件。
这将避免控制台中出现警告消息。

尝试:

 profits<-reactive({
    req(input$pro>0,
        input$prof>0,
        input$profs>0,
        input$profit>0,
        input$profits>0)
    
    as.numeric(c(input$pro,
                 input$prof,
                 input$profs,
                 input$profit,
                 input$profits
    ))
})

另一种选择是使用 validate 以便在不满足条件时显示有用的信息消息:

  profits<-reactive({
    validate(need(input$pro>0 &
                  input$prof>0 &
                  input$profs>0 &
                  input$profit>0 &
                  input$profits>0,'Please fill all coefs'))
    
    as.numeric(c(input$pro,
                 input$prof,
                 input$profs,
                 input$profit,
                 input$profits
    ))
  })

enter image description here

关于r - Ggplot2 在 Shiny 的应用程序中显示错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63860037/

相关文章:

r - 在另一个模块中使用一个 Shiny 模块的变量值

html - 图像 for 单选按钮 r Shiny

r - dplyr:如何按子组标准过滤组

r - 计算多个变量的多个组之间的倍数变化的快速而优雅的方法?

r - 如何根据每组中的累积值对堆栈条进行排序

r - dateRangeInput ui 的一部分隐藏在 Shiny 的仪表板标题下

R Markdown - 打印文档中使用的所有代码片段的简洁方法

从 Shiny 模块中嵌套的 `selectInput` 返回值

r - 使用极慢的循环在 R 中生成交互式部分依赖图

r - 当角度在 45 和 90 之间时,如何更正 x 轴文本放置?