Atius
Atius

Reputation: 191

Plotly in shiny - R - text causing error if data is missing

I am making a shiny app which filters and summarises a lot of data. It works for the most part. But I am bound by laws to limit what shows up in the graphs so I filter away everything below 5(as can be seen in the code.) This causes some variables to be rendered as zero and because I have text in the add_trace it throws me an error (Column text must be length 0, not 1). I am trying to find away to either get a text output if the plot is empty, or prevent the error from showing up.

It might also help me if I could just render something else (custom message) if the output throws an error.

Here is a reproducible example,
The error will show up if you change the school to Hogwarths.

My data:

mydata <- structure(list(year = c("2001", "2002", "2001", "2002", "2001","2002", "2001", "2002", "2001", "2002", "2001", "2002", "2001", "2002", "2001", "2002", "2001", "2002", "2001", "2001", "2002"), school = structure(c(2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Beauxbatons", "Hogwarths"), class = "factor"), grade = c(67, 69, 72, 90, 75, 85, 13, 45, 12, 90, 75, 85, 13, 45, 12, 67, 69, 72, 67, 69, 72), magic = structure(c(1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("black", "white"), class = "factor")), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"))

my shiny app:

library(shiny)
library(tidyverse)

ui <- fluidPage(

    selectInput("school",
            label = h3("Choose a school"),
            choices = levels(mydata$school)
    ),
    ### Choose type of magic
    selectInput("magic",
                label = "Choose magic type",
                choices = levels(mydata$magic)),


    plotlyOutput("plot_school")

)

server <- function(input, output) {

    output$plot_school <- renderPlotly({

            mydata %>%
                    filter(school == input$school, magic == input$magic) %>% 
                    group_by(year) %>% 
                    summarise(m = mean(grade), n=n()) %>%
                    filter(n > 5) %>% 
                    plot_ly(type = "scatter") %>%
                    add_trace(
                            x = ~ year,
                            y = ~ m,
                            text = ~paste('number: ', n),
                            type = 'bar'
                    )
    }) 
}
# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 1018

Answers (1)

Vishesh Shrivastav
Vishesh Shrivastav

Reputation: 2129

You can do this using validate. It checks for a condition using need, proceeds if the condition is met otherwise displays a custom message for the user.

You can first filter your data based on (n > 5). Then check if this data has any rows. If yes, plot it and if not, throw a message.

output$plot_school <- renderPlotly({

    filtered_data <- mydata %>%
        filter(school == input$school, magic == input$magic) %>% 
        group_by(year) %>% 
        summarise(m = mean(grade), n=n()) %>%
        filter(n > 5)

    # Add validate - checks if number of rows in filtered_data is > 0
    # If not, displays "Data insufficient for plot"
    validate(
      need( nrow(filtered_data) > 0, "Data insufficient for plot")
    )

    # Create plot
    filtered_data %>%
      plot_ly(type = "scatter") %>%
      add_trace(
        x = ~ year,
        y = ~ m,
        text = ~paste('number: ', n),
        type = 'bar'
      )
  })

Read more about validate here.

Upvotes: 2

Related Questions