如何更改“惰性”闪亮函数的错误消息?

问题描述 投票:0回答:1

这是我制作的较大脚本的简化版本。本质上我有 3 个图表,第一个图表使用用户输入数据集总行数的百分比并绘制它。第二个图表使用第一个图表中未绘制的行,应用不同的百分比选择器并绘制它。第三张图做了同样的事情,但相对于第二张图。

我的问题是第二个图能够返回自定义错误消息,因为数据集可用,但因为闪亮是“懒惰”,我无法查询第三个图数据,因为它还不存在。我想这样做是为了将错误消息更改为对用户更有用的错误消息。

运行下面的代码时,第二张图有自定义错误,但第三张图显示

"Error: argument is of length zero"
但我希望它显示自定义错误。我知道我可以使用

validate(
  need(nrow(Graph1_data_inverse()) > 0, 'There is no data available for this graph')
)

validate(
  need(nrow(Graph2_data_inverse()) > 0, 'There is no data available for this graph')
)

但如果可能的话,我想要一个更优雅的解决方案。

library(shiny)
library(datasets)
library(shinyFeedback)
library(plotly)
data <- iris


ui <- fluidPage(
  shinyFeedback::useShinyFeedback(),
  
  column(4,
         numericInput("Graph1_percent", tags$span(style="color: #000000; font-size: 13px;", "Percent (%)"), value = 100, min = 0, max = 100),
         plotlyOutput("Graph1", height = 400)
  ),
  column(4,
         numericInput("Graph2_percent", tags$span(style="color: #000000; font-size: 13px;", "Percent (%)"), value = 100, min = 0, max = 100),
         plotlyOutput("Graph2", height = 400)
  ),
  column(4,
         numericInput("Graph3_percent", tags$span(style="color: #000000; font-size: 13px;", "Percent (%)"), value = 100, min = 0, max = 100),
         plotlyOutput("Graph3", height = 400)
  )
  
)

server <- function(input, output, session) {
  
  Graph1_data <- reactive({
    n <- nrow(data)
    if(input$Graph1_percent == 0 | n == 0) {
    } else {
      Graph1_data_ <- data[1:round(n*(input$Graph1_percent /100)), ]
    }
  })
  
  Graph1_data_inverse <- reactive({
    n <- nrow(data)
    if(n == 0 | input$Graph1_percent == 100) {
    } else {
      Graph1_data_inv <- data[(round(n*(input$Graph1_percent /100))+1):n, ]
    }
  })
  
  output$Graph1 <- renderPlotly({
    
    ggplotly(Graph1_data() %>%
               ggplot(aes(x = Sepal.Length, fill = Species))+
               geom_bar()
    )
  })
  
  ###Graph 2
  Graph2_data <- reactive({
    validate(
      need(nrow(Graph1_data_inverse()) > 0, 'There is no data available for this graph.')
    )
    
    n <- nrow(Graph1_data_inverse())
    if(input$Graph2_percent == 0 | n == 0) {
    } else {
      Graph2_data_ <- Graph1_data_inverse()[1:round(n*(input$Graph2_percent /100)), ]
    }
    
  })
  
  Graph2_data_inverse <- reactive({
    n <- nrow(Graph1_data_inverse())
    if(n == 0 | input$Graph2_percent == 100) {
    } else {
      Graph2_data_inv <- Graph1_data_inverse()[(round(n*(input$Graph2_percent /100))+1):n, ]
    }
  })
  
  output$Graph2 <- renderPlotly({
    req(Graph2_data())
    
    ggplotly(Graph2_data() %>%
               ggplot(aes(x = Sepal.Length, fill = Species))+
               geom_bar()
    )
  })
  
  ###Graph 3
  Graph3_data <- reactive({
    
    ###This section doesn't work
    exists <- exists("Graph2_data_inverse", where = -1, mode='function')
    if(exists != TRUE){
      paste("There is no data available for this graph")
      }
    req(exists, cancelOutput = TRUE)
    
    validate(
      need(nrow(Graph2_data_inverse()) > 0, 'There is no data available for this graph')
    )
    
    n <- nrow(Graph2_data_inverse())
    if(input$Graph3_percent == 0 | n == 0) {
    } else {
      Graph3_data_ <- Graph2_data_inverse()[1:round(n*(input$Graph3_percent /100)), ]
    }
    
  })
  
  ###this inverse dataset is not used but I'm including it here so the graphs retain the same structure
  Graph3_data_inverse <- reactive({
    n <- nrow(Graph2_data_inverse())
    if(n == 0 | input$Graph3_percent == 100) {
    } else {
      Graph3_data_inv <- Graph2_data_inverse()[(round(n*(input$Graph3_percent /100))+1):n, ]
    }
  })
  
  output$Graph3 <- renderPlotly({
    req(Graph3_data())
    
    ggplotly(Graph3_data() %>%
               ggplot(aes(x = Sepal.Length, fill = Species))+
               geom_bar()
    )
  })
  
}
# Run the application 
shinyApp(ui = ui, server = server)
r shiny shiny-reactivity
1个回答
0
投票

当您检查跟踪日志时,您应该注意到错误并不是真正源自

Graph3_data()
,而是
Graph2_data_inverse()
未能通过 Error in if 进行评估:

Warning: Error in if: argument is of length zero
  150: <reactive:Graph2_data_inverse> [#43]
  134: Graph2_data_inverse
  126: <reactive:Graph3_data> [#68]
  110: Graph3_data
  103: renderPlotly [#92]
  102: func
   99: shinyRenderWidget
   98: func
   85: renderFunc
   84: output$Graph3
    3: runApp
    2: print.shiny.appobj
    1: <Anonymous>

这又是在

NULL
条件下具有潜在 | 值和元素
OR
if
的结果。 例如。如果您有以下反应:

  Graph2_data_inverse <- reactive({
    n <- nrow(Graph1_data_inverse())
    if(n == 0 | input$Graph2_percent == 100) {
    } else {
      Graph2_data_inv <- Graph1_data_inverse()[(round(n*(input$Graph2_percent /100))+1):n, ]
    }
  })

并且

Graph1_data_inverse()
恰好返回
NULL
,你会得到类似:

(n <- nrow(NULL))
#> NULL
if (n == 0 | FALSE ) {}
#> Error in if (n == 0 | FALSE) {: argument is of length zero

if
条件下,您最有可能想要使用
||
&&
而不是
|
&
。如果
NULL
值有可能潜入并将整个表达式转换为 0 长度/非
TRUE/FALSE
,则
shiny::isTruthy()
会很方便,但由于
0
也是如此,因此可能需要进行最小更新像这样:

  Graph2_data_inverse <- reactive({
    n <- nrow(Graph1_data_inverse())
    if(isTruthy(n) || n == 0 || input$Graph2_percent == 100) {
       ... 
    }
  })

这适用于所有条件,而不仅仅是

Graph2_data_inverse()
中的条件。

© www.soinside.com 2019 - 2024. All rights reserved.