Search code examples
rshinyflexdashboard

better error handling when dynamic input selections cause problems for reactive objects embedded in inline flexdashboard chart notes


How can I avoid error messages in my flexdashboard chart notes when dynamic filtering and faceting creates problems in the data? For instance, here's an example where a select input causes there to be no data.

enter image description here

---
title: "Example"
runtime: shiny
output:
  flexdashboard::flex_dashboard:
    vertical_layout: fill
---


```{r}
  library(tidyverse)
  library(flexdashboard)
```


### Chart 1

```{r}

df <- fortify(forecast::gold)

fillCol(height = "100%", flex = c(1, NA), 
    plotOutput("plot", height = "100%"),
    wellPanel(
      tags$style(".well {background-color:#ffffff; border-color:#ffffff;}"),
      radioButtons("myInput", label = NULL,
        choices = list("All" = "all",
                       "Problematic filtering" = "filter"),
        selected = "all", inline=T)
      )
    )

output$plot <- renderPlot({
  ggplot(df, aes(x, y)) + 
         geom_line() 
})

notes <- reactive({
  if (input$myInput=="all") {
    df %>%
      summarise(mean = mean(y, na.rm=TRUE)) %>%
      pull(mean)
  } else {
    df %>%
      filter(x==0) %>%
      summarise(mean = mean(y, na.rm=TRUE)) %>%
      pull(mean)
    }
  })

# new attempt
notes_ <- reactive({

notes <- notes()

  if (exists("notes") & !is.na(notes) & !is.nan(notes)) {
    print(notes)
    } else {
    print("[not available]")
    }

  })
```

> The mean is `r notes_`.

Attempt

This prints "[not available]" (integrated above). Is there a better approach?

# new attempt
notes_ <- reactive({

notes <- notes()

  if (exists("notes") & !is.na(notes) & !is.nan(notes)) {
    print(notes)
    } else {
    print("[not available]")
    }

  })
```

> The mean is `r notes_`.

Solution

  • This prints "[not available]". Open to better solutions...

    ---
    title: "Example"
    runtime: shiny
    output:
      flexdashboard::flex_dashboard:
        vertical_layout: fill
    ---
    
    
    ```{r}
      library(tidyverse)
      library(flexdashboard)
    ```
    
    
    ### Chart 1
    
    ```{r}
    
    df <- fortify(forecast::gold)
    
    fillCol(height = "100%", flex = c(1, NA), 
        plotOutput("plot", height = "100%"),
        wellPanel(
          tags$style(".well {background-color:#ffffff; border-color:#ffffff;}"),
          radioButtons("myInput", label = NULL,
            choices = list("All" = "all",
                           "Problematic filtering" = "filter"),
            selected = "all", inline=T)
          )
        )
    
    output$plot <- renderPlot({
      ggplot(df, aes(x, y)) + 
             geom_line() 
    })
    
    notes <- reactive({
      if (input$myInput=="all") {
        df %>%
          summarise(mean = mean(y, na.rm=TRUE)) %>%
          pull(mean)
      } else {
        df %>%
          filter(x==0) %>%
          summarise(mean = mean(y, na.rm=TRUE)) %>%
          pull(mean)
        }
      })
    
    notes_ <- reactive({
    
    notes <- notes()
    
      if (exists("notes") & !is.na(notes) & !is.nan(notes)) {
        print(notes)
        } else {
        print("[not available]")
        }
    
      })
    ```
    
    > The mean is `r notes_`.