1

I'm working on a Shiny dashboard for a personal project with some football stats. Whenever I change the statistic to be graphed and/or the filter, I get the same players that were in the first dataset. For example, when I start the app, the app creates a graph of the top ten rushers in school history with a filter of rushing attempts >= 0. When I change the statistic selection to rushing average, however, those ten players are the ones shown, which is incorrect.

library(readxl)
library(tidyverse)
library(purrr)
library(shiny)

interface <- fluidPage(
    titlePanel(" "), 
    sidebarLayout(
        sidebarPanel(
            h1("Stats!"), 
            selectInput("stat_selection", 
                        label = "Select a season statistics", 
                        choices = c("Rushing Yards",
                                    "Rushing Touchdowns",
                                    "Rushing Average",
                                    "Reciving Yards",
                                    "Receptions",
                                    "Receiving Touchdowns",
                                    "Receiving Average"),
                        selected = "Rushing Yards"), 
            selectInput("filter_input", 
                        label = "Select a statistic to filter by", 
                        choices = c("Rushing Yards",
                                    "Rushing Touchdowns",
                                    "Rushing Average",
                                    "Rushing Attempts",
                                    "Reciving Yards",
                                    "Receptions",
                                    "Receiving Touchdowns",
                                    "Receiving Average"),
                        selected = "Rushing Attempts"), 
            numericInput("filter_number", 
                         label = "Type a number for the filter (>=)", 
                         value = 0, min = 0), 
            actionButton("button", "Graph")), 
        mainPanel(
            plotOutput("plot_button"),
            tableOutput("table_button")
        )
    )
)

server_osu <- function(input, output) {
    dataInput <- reactive({
        switch(input$stat_selection, 
               "Rushing Yards" = rush_yds, 
               "Rushing Touchdowns" = rush_tds, 
               "Rushing Average" = rush_avg,
               "Reciving Yards" = rec_yds,
               "Receptions" = rec_rec,
               "Receiving Touchdowns" = rec_td,
               "Receiving Average" = rec_avg)
    })
    filterInput <- reactive({
        switch(input$filter_input, 
               "Rushing Yards" = rush_yds, 
               "Rushing Touchdowns" = rush_tds, 
               "Rushing Average" = rush_avg,
               "Rushing Attempts" = rush_att,
               "Reciving Yards" = rec_yds,
               "Receptions" = rec_rec,
               "Receiving Touchdowns" = rec_td,
               "Receiving Average" = rec_avg)
    })
    filter_number <- reactive(as.double(input$filter_number))
    table_button_react <- eventReactive(input$button, {
        dataset <- dataInput()
        val <- filter_number()
        colnames(dataset)[1] = "Player and Season"
        dataset_filter <- filterInput()
        colnames(dataset_filter)[1] = "Player and Season"
        dataset <- left_join(dataset, dataset_filter)
        colnames(dataset)[1] = "Player and Season"
        og <- colnames(dataset)[3]
        colnames(dataset)[3] = "filter"
        original <- colnames(dataset)[2]
        colnames(dataset)[2] = 'selected'
        dataset <- dataset %>% 
            filter(filter >= val)
        dataset <- dataset %>% 
            top_n(10) %>% 
            arrange(-selected)
        colnames(dataset)[2] = original
        colnames(dataset)[3] = og
        dataset
    })
    plot_button_react <- eventReactive(input$button, {
        dataset <- dataInput()
        val <- filter_number()
        colnames(dataset)[1] = "Player and Season"
        dataset_filter <- filterInput()
        colnames(dataset_filter)[1] = "Player and Season"
        dataset <- left_join(dataset, dataset_filter)
        colnames(dataset)[1] = "Player and Season"
        colnames(dataset)[2] = "selected"
        colnames(dataset)[3] = "filter"
        dataset <- dataset %>% 
            filter(filter >= val)
        top_ten <- dataset %>% top_n(10)
        min = min(top_ten$selected)
        max = max(top_ten$selected)
        ggplot(top_ten, aes(x = reorder(`Player and Season`, -selected), y = selected)) +
            geom_bar(stat = 'identity') + theme_minimal() + xlab('SEASON') +
            ylab(input$stat_selection) + theme(text=element_text(size=16)) +
            scale_fill_manual(values = c('#BBBBBB', '#BB0000')) +
            theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
            theme(legend.position = 'none') +
            coord_cartesian(ylim=c(min - 0.05*min, max + 0.05*max)) +
            theme(axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 10))) +
            theme(axis.title.x = element_text(margin = margin(t = 10, r = 0, b = 10, l = 0))) +
            theme(axis.text.y = element_text(size=14),
                  axis.title=element_text(size=16,face='bold')) + 
            labs(caption = '')
    })
    output$plot_button <- renderPlot({
        plot_button_react()
    })
    output$table_button <- renderTable({
        table_button_react()
    })
}
  • Football? Oh, you mean "soccer"! ;) Seriously, it would be easier to help you if you included some input data and cut out some of the irrelevant functionality in your app. That would make it easier to help you. See [this post](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610#5963610) for advice on how to make a imple self-contained example, or reprex. – Limey May 31 '20 at 08:18

1 Answers1

0

As I mentioned above, a reprex - including input data - would help us to help you. That said, I think the problem is that your XXX_button_reacts depend only on input$button. They don't depend on input$stat_selection, input$filter_number or input$filter_input. That's why they don't update as you want them to.

The fix is easy. Just add them (in a call to req() if you like) at the top of each XXXX_button_react, for example:

plot_button_react <- eventReactive(input$button, {
  input$stat_selection
  input$filter_number
  input$filter_input

  <your code here>
})

As a point of style, I feel it's better to separate data generation from data presentation. It makes the logic of your code more obvious, reduces the chance of errors, reduces the need for code duplication and makes your code more reusable.

In your case, I would create a reactive that holds the data you wish to tablulate and plot and then reference that reactive in each of your render_XXXX functions. That would also remove the need for your input$button: the plot and graph would each update automatically whenever you changed one of your other input widgets.

Limey
  • 10,234
  • 2
  • 12
  • 32