Reputation: 191
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
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