1

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

})
Zhilong Jia
  • 2,329
  • 1
  • 22
  • 34

2 Answers2

5

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

Zhilong Jia
  • 2,329
  • 1
  • 22
  • 34
Mike Wise
  • 22,131
  • 8
  • 81
  • 104
  • It's a solution. But kind of complex. I used textOutput() and renderText() to show some information if it's not a warning. Thank you. – Zhilong Jia Dec 23 '15 at 12:20
  • 1
    You can omit the textOutput("warnstat") if you add the following to your server function: outputOptions(output, "warnstat", suspendWhenHidden=FALSE) – Joe Cheng Dec 24 '15 at 09:05
1

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

ahmohamed
  • 2,920
  • 20
  • 35