Zhilong Jia
Zhilong Jia

Reputation: 2359

show warning to user in shiny in R

How to show warning to user in shiny in R. The user's input is correct, but the output is not suitable to show. The aim is to remind the user only a subset data are shown due to too many. warning() is shown in console only. Thank you.

Here is a fake code to explain the question due to the original is long. There is a warning in the renderTable. it aims to check data if the data is big, only first several items will be shown.

ui.R

shinyUI(fluidPage(

titlePanel("Validation App"),

sidebarLayout(
    sidebarPanel(
        selectInput("data", label = "Data set",
                    choices = c("", "mtcars", "faithful", "iris"))
    ),

    # Show a plot of the generated distribution
    mainPanel(
        tableOutput("table"),
        plotOutput("plot")
    )
)
))

server.R

shinyServer(function(input, output) {

data <- reactive({ 

    validate(
        need(input$data != "", "Please select a data set")
    )
    get(input$data, 'package:datasets') 

})


output$plot <- renderPlot({
    hist(data()[, 1], col = 'forestgreen', border = 'white')
})

output$table <- renderTable({
    warning("Warning message.")
    head(data())
})

})

Upvotes: 1

Views: 6526

Answers (2)

ahmohamed
ahmohamed

Reputation: 2970

I use this wrapping function to capture errors, warnings and messages and display them as dismissible notifications to the user.

quietly <- function(.f) {
  fun <- .f %>% purrr::quietly() %>% purrr::safely()
  function(...) {
    res <- fun(...)

    if(!is.null(res$error)) {  # safely output
      showNotification(res$error$message, duration = 10, type="error")
      return(res$result)
    }
    res <- res$result # quietly output
    if(!is.null(res$warnings) && length(res$warnings) > 0) {
      lapply(unique(res$warnings), showNotification, duration = 10, type="warning")
    }
    return(res$result)
  }
}

Upvotes: 1

Mike Wise
Mike Wise

Reputation: 22817

Update:

I put some more work into this and made the warning panel conditional.

However it only works if I include out the textOutput("warnstat") on every page. I assume because it is not setting the javascript variable output.warnstat unless I do this.


You could just build a warning panel into your UI, and set it accordingly. Here is a simple example, but it could be more elaborate than just a verabtim print statement.

ui.r

    shinyUI(fluidPage(

      titlePanel("Validation App"),

      sidebarLayout(
        sidebarPanel(
          selectInput("data", label = "Data set",
                      choices = c("", "mtcars", "faithful", "iris"))
        ),

        # Show a plot of the generated distribution

        mainPanel(
          conditionalPanel(condition = "output.warnstat == 'Error'",
                           verbatimTextOutput("warnmsg")),
          tableOutput("table"),
          plotOutput("plot")
        )
      )
    ))

server.r

shinyServer(function(input, output) {

  errstat <- reactive({
    ifelse (input$data=="mtcars",T,F)
  })

  data <- reactive({
    validate(
      need(input$data != "", "Please select a data set")
    )
    get(input$data, 'package:datasets')

  })


  output$plot <- renderPlot({
    hist(data()[, 1], col = 'forestgreen', border = 'white')
  })

  output$table <- renderTable({
    warning("Warning message.")
    head(data())
  })
  output$warnmsg <- renderPrint({
    if (errstat()){
      print("Warning message - blah blah blah")
      print(input$data)
      head(data())
    } else {
      print("No error")
    }
  })
  output$warnstat <- renderText({ifelse(errstat(),"Error","No error") })
  outputOptions(output, "warnstat", suspendWhenHidden=FALSE)
})

With conditional warning panel:

enter image description here

Without conditional warning panel:

enter image description here

Upvotes: 5

Related Questions