0

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)

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.