4
votes

I am trying to create a dashboard in shiny with 2 visualizations (datatable and bargraph) that will allow the user to apply the same filters to both visualizations simultaneously. I tried using the solution shown here but I guess I am missing something. "Data5" is the name of the data frame I am using to populate. Any help would be appreciated.

server.R

library(shiny)
library(ggplot2)
library(dplyr)

dt <- data5

shinyServer(function(input, output) {


data <- reactive({data5
    if (input$year != "All"){
      data <- data[data5$year == input$year,]
    }
   if (input$month != "All"){
      data <- data[data5$month == input$month,]
    }
   if (input$partner_name != "All"){
      data <- data[data5$partner_name == input$partner_name,]
    }
    if (input$cube_title != "All"){
      data <- data[data5$cube_title == input$cube_title,]
    }

  })

  #plots
  output$table1 <- renderDataTable({
    data
  })

  output$plot1 <- renderPlot({
    ggplot(data=subset(data5,cube_title=="Leads"), aes(x=month,y=f0_)) + geom_bar(fill="blue", stat = "identity") + ylab("Leads") + ggtitle("Leads")
  })
  output$plot2 <- renderPlot({
    ggplot(data=subset(data5,cube_title==c("CommunityProfileViews","HomeProfileViews")), aes(x=month,y=f0_)) + geom_bar(fill="blue", stat = "identity") + ylab("Profile Views") + ggtitle("Profile Views")

  })

})

ui.R

dashboardPage(
  skin = "blue",
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(
     ( 
          selectInput("year", 
                      "Year:", 
                      c("All", 
                        unique(as.character(data5$year))))
      ),
      ( 
          selectInput("month", 
                      "Month:", 
                      c("All", 
                        unique(as.character(data5$month))))
      ),
      (
          selectInput("partner_name", 
                      "Partner:", 
                      c("All", 
                        unique(as.character(data5$partner_name))))
                        ),
      (
          selectInput("cube_title", 
                      "Metric:", 
                      c("All", 
                        unique(as.character(data5$cube_title))))
      )        
    ),

  dashboardBody(


     tabsetPanel(id = "tabSelected",
                tabPanel("Charts", plotOutput("plot1"), 
                box(plotOutput("plot2"))),
                tabPanel("DataTable", dataTableOutput("table1"))
    )

               )
            )
1

1 Answers

4
votes

Issue 1: reactive returns a function, not an object. So we need to call data(), not data, in your renderDataTable and renderPlot functions

Issue 2: you need to put data() in your render functions. Currently, it is calling data5, which is not reactive:

output$plot1 <- renderPlot({
    Temp <- data()
    ggplot(data=subset(Temp,cube_title=="Leads"), aes(x=month,y=f0_)) + geom_bar(fill="blue", stat = "identity") + ylab("Leads") + ggtitle("Leads")
}) 

Issue 3: Your reactive function returns an assignment call. I would do this more like:

data <- reactive({ #The data5 that was here is not necessary
  temp <- data5 
  if (input$year != "All"){
    temp <- temp[temp$year == input$year,]
  }
  if (input$month != "All"){
    temp <- temp[temp$month == input$month,]
  }
  if (input$partner_name != "All"){
    temp <- temp[temp$partner_name == input$partner_name,]
  }
  if (input$cube_title != "All"){
    temp <- temp[temp$cube_title == input$cube_title,]
  }
  return(temp)

})

so that now when we call data(), we return our filtered data.frame

Issue 4: (albeit less of an issue) I would avoid using data as an object name. It means something else and can often get confusing when reading code. Use the safer DT or something else. You can always check if a name is in use by typing exists("NameToCheck") in the console.

Suggested Reading