3

I have a shiny App and would like to add a "Reset" button to clear all inputs. This is particularly useful if one has several inputs and does not want to reset each manually.

I tried the idea given here. It somewhat works in a buggy way but for some reason it prints the names of the variables above the reset button, ie. "categ_1", "date", "categ_2". Also, I don't know how to combine update & uiOutput in the below line:

 output$resetable_input <- renderUI({
         times <- input$reset_input
         div(
           id=letters[(times %% length(letters)) + 1],
           #                updateuiOutput(session,"firm"),
           updateSelectInput(session,"categ_1",
                             choices = c("All",unique(as.character(df$CATEG_1)))),
           updateSelectInput(session,"date", 
                             choices = c("All","Last 28 Days","Last Quarter")),
           updateSelectInput(session,"categ_2",
                             choices = c("All",unique(as.character(df$CATEG_2))))
         )
       })

Has anyone found an easy way to do this?

Many Thanks in advance!

  1. Create sample data

      set.seed(1)
      df <- data.frame(FIRM=rep(LETTERS[1:7],each=10), CATEG_1=rbinom(70,4,0.9),CATEG_2=rbinom(70,1,0.2),date=as.Date("2014-01-01")+1:10,y1=sample(1:100,70))
    
  2. shiny App

     library(shiny)
     library(rCharts)
     library(doBy)
     library(plyr)
    
      shinyApp(ui = 
       shinyUI(pageWithSidebar(
    
         # Application title
         headerPanel("Example"),
    
         sidebarPanel(
           uiOutput("firm"),
           #  selectInput("firm", "Filter by firm:", 
           #   choices = unique(as.character(df))),
           selectInput("categ_1", "Filter by Category 1:",
                       choices = c("All",unique(as.character(df$CATEG_1)))),
           selectInput("date", "Filter by Date:", 
                       choices = c("All","Last 28 Days","Last Quarter")),
           selectInput("categ_2", "Filter by Category 2:", 
                       choices = c("All",unique(as.character(df$CATEG_2)))),
           uiOutput('resetable_input'),
           actionButton("reset_input", "Reset inputs")         
         ), #sidebarPanel
    
         mainPanel(
           h4("Example plot",style = "color:grey"),
           showOutput("plot", "nvd3")
         ) # mainPanel
       ) #sidebarLayout
       ) #shinyU
     , 
     server = shinyServer(function(input, output, session) {  
    
       subset_data <- reactive({df <- filter_data(df,input$firm,
                                                  input$date,
                                                  input$categ_1,
                                                  input$categ_2)
                                shiny::validate(need(!is.null(df),"No data to display"))
                                return(df)})
    
       output$firm <- renderUI({
         input$date
         input$categ_1
         input$categ_2
         selectInput("firm", "Filter by Firm:",
                     choices = c("All",as.character(unique(isolate(subset_data()$FIRM)))))
       })
    
          output$resetable_input <- renderUI({
         times <- input$reset_input
         div(
           id=letters[(times %% length(letters)) + 1],
           #                updateuiOutput(session,"firm"),
           updateSelectInput(session,"categ_1",
                             choices = c("All",unique(as.character(df$CATEG_1)))),
           updateSelectInput(session,"date", 
                             choices = c("All","Last 28 Days","Last Quarter")),
           updateSelectInput(session,"categ_2", 
                             choices = c("All",unique(as.character(df$CATEG_2))))
         )
       })
    
    
    
       output$plot<-renderChart2({ build_plot(subset_data()) })
    
       ##############
       #below are the functions used in the code
       ##############
    
       # function for date subsetting 
    
       filter_date<-function(df,dateRange="All"){
         filt <- df
         td <- max(as.Date(filt$date))
         if (dateRange=='Last 28 Days'){filt <-filt[filt$date>=(td-28),]}
         if (dateRange=='Last Quarter'){filt <-filt[filt$date>=(td-84),]}
         return(filt)
       }  # filter by date
    
       # function for data subsetting 
    
       filter_data<-function(df,firm=NULL,dateRange="All",categ_1=NULL,categ_2=NULL)
       { 
         filt<-filter_date(df,dateRange)
    
         if (!is.null(firm)) {
           if(firm!='All') {filt <- filt[filt$FIRM==firm,]}
         }
         if (!is.null(categ_1)){
           if (categ_1!='All') {filt <- filt[filt$CATEG_1==categ_1,]}
         } 
         if (!is.null(categ_2)) {
           if (categ_2!='All') {filt <- filt[filt$CATEG_2==categ_2,]} 
         }
    
         if(nrow(filt)==0) {filt <- NULL}
         return(filt)
       } # prepare data to be plotted
    
       # function to create plot
    
       build_plot <- function(df) {
         plotData<-df
         # If 1 firms selected, time series is shown  
         if (length(as.character(unique(plotData$FIRM)))==1) {
    
           tabledta<-summaryBy(y1~FIRM+date,data=plotData,FUN=sum,keep.names=TRUE) 
    
           filler = expand.grid(FIRM=as.character(unique(df$FIRM)),
                                date=seq(min(tabledta$date),max(tabledta$date),by='1 day'))
           df = merge(filler,
                      tabledta,
                      by=c('date','FIRM'),
                      all.x=T)
           df[is.na(df)]=0
           p <- nPlot(y1 ~ date, group = 'FIRM', data = df, type = 'lineChart')
           p$chart(margin=list(left=150))
           p$yAxis(showMaxMin = FALSE)
           p$xAxis(tickFormat ="#!function(d) {return d3.time.format('%Y-%m-%d')(new Date(d * 24 * 60 * 60 * 1000));}!#")
           p
         }
         # If "All" firms are selected, barchart of Top 5 is shown
         else{
           SummaryTab<-aggregate(y1~FIRM,data=plotData,FUN=sum)
           SummaryTab$rank=rank(SummaryTab$y1)
           SummaryTab$rank[SummaryTab$rank>5]<-6
    
           if (length(SummaryTab$rank)>5) {
             #Top 5 firms in terms of y1 are shown
             top5<-SummaryTab[SummaryTab$rank<=5,]
             # other firms are collapsed, shown as 1 entry
    
             others<-aggregate(y1~rank,data=SummaryTab,FUN=sum)  
             others<-others[others$rank==6,]
             others$FIRM<-"Others"
    
             # Create the summarytable to be plotted
             plotData=rbind(top5,others)}
    
           tabledta<-summaryBy(y1~FIRM,data=plotData,FUN=sum,keep.names=TRUE) 
           tabledta<-arrange(tabledta,y1) 
           #   if(is.null(tabledta)) {print("Input is an empty string")}
    
           p <- nPlot(y1 ~ FIRM,data = tabledta, type = 'multiBarHorizontalChart')    
           p$chart(margin=list(left=150))
           p$yAxis(showMaxMin = FALSE)
           p
         }
    
       }
     }) #shinyServer
      ) 
    
Community
  • 1
  • 1
TinaW
  • 989
  • 1
  • 18
  • 28

1 Answers1

4
  1. The selectInput sections in the ui.R file are not needed any longer, because you are going to replace them by the dynamically generated selectInput.

  2. There should not be UpdateSelectInput in the output$resetable_input expression -- it should be just the same selectInput that you used to have in ui.R.

  3. The div and id things are useless (to the best of my knowledge) in the output$resetable_input expression, you can safely replace them by list():

    set.seed(1)
    df <- data.frame(FIRM=rep(LETTERS[1:7],each=10), CATEG_1=rbinom(70,4,0.9),CATEG_2=rbinom(70,1,0.2),date=as.Date("2014-01-01")+1:10,y1=sample(1:100,70))
    
     library(shiny)
     library(rCharts)
     library(doBy)
     library(plyr)
    
      shinyApp(ui = 
       shinyUI(pageWithSidebar(
    
         # Application title
         headerPanel("Example"),
    
         sidebarPanel(
           uiOutput("firm"),
           #  selectInput("firm", "Filter by firm:", 
           #   choices = unique(as.character(df))),
           #selectInput("categ_1", "Filter by Category 1:",
                       #choices = c("All",unique(as.character(df$CATEG_1)))),
           #selectInput("date", "Filter by Date:", 
                       #choices = c("All","Last 28 Days","Last Quarter")),
           #selectInput("categ_2", "Filter by Category 2:", 
                       #choices = c("All",unique(as.character(df$CATEG_2)))),
           uiOutput('resetable_input'),
           actionButton("reset_input", "Reset inputs")         
         ), #sidebarPanel
    
         mainPanel(
           h4("Example plot",style = "color:grey"),
           showOutput("plot", "nvd3")
         ) # mainPanel
       ) #sidebarLayout
       ) #shinyU
     , 
     server = shinyServer(function(input, output, session) {  
    
       subset_data <- reactive({df <- filter_data(df,input$firm,
                                                  input$date,
                                                  input$categ_1,
                                                  input$categ_2)
                                shiny::validate(need(!is.null(df),"No data to display"))
                                return(df)})
    
       output$firm <- renderUI({
         input$date
         input$categ_1
         input$categ_2
         selectInput("firm", "Filter by Firm:",
                     choices = c("All",as.character(unique(isolate(subset_data()$FIRM)))))
       })
    
          output$resetable_input <- renderUI({
         times <- input$reset_input
         div(
           id=letters[(times %% length(letters)) + 1],
           selectInput("categ_1", "Filter by Category 1:",
                       choices = c("All",unique(as.character(df$CATEG_1)))),
           selectInput("date", "Filter by Date:", 
                       choices = c("All","Last 28 Days","Last Quarter")),
           selectInput("categ_2", "Filter by Category 2:", 
                       choices = c("All",unique(as.character(df$CATEG_2))))
         )
       })
    
    
    
       output$plot<-renderChart2({ build_plot(subset_data()) })
    
       ##############
       #below are the functions used in the code
       ##############
    
       # function for date subsetting 
    
       filter_date<-function(df,dateRange="All"){
         filt <- df
         td <- max(as.Date(filt$date))
         if (dateRange=='Last 28 Days'){filt <-filt[filt$date>=(td-28),]}
         if (dateRange=='Last Quarter'){filt <-filt[filt$date>=(td-84),]}
         return(filt)
       }  # filter by date
    
       # function for data subsetting 
    
       filter_data<-function(df,firm=NULL,dateRange="All",categ_1=NULL,categ_2=NULL)
       { 
         filt<-filter_date(df,dateRange)
    
         if (!is.null(firm)) {
           if(firm!='All') {filt <- filt[filt$FIRM==firm,]}
         }
         if (!is.null(categ_1)){
           if (categ_1!='All') {filt <- filt[filt$CATEG_1==categ_1,]}
         } 
         if (!is.null(categ_2)) {
           if (categ_2!='All') {filt <- filt[filt$CATEG_2==categ_2,]} 
         }
    
         if(nrow(filt)==0) {filt <- NULL}
         return(filt)
       } # prepare data to be plotted
    
       # function to create plot
    
       build_plot <- function(df) {
         plotData<-df
         # If 1 firms selected, time series is shown  
         if (length(as.character(unique(plotData$FIRM)))==1) {
    
           tabledta<-summaryBy(y1~FIRM+date,data=plotData,FUN=sum,keep.names=TRUE) 
    
           filler = expand.grid(FIRM=as.character(unique(df$FIRM)),
                                date=seq(min(tabledta$date),max(tabledta$date),by='1 day'))
           df = merge(filler,
                      tabledta,
                      by=c('date','FIRM'),
                      all.x=T)
           df[is.na(df)]=0
           p <- nPlot(y1 ~ date, group = 'FIRM', data = df, type = 'lineChart')
           p$chart(margin=list(left=150))
           p$yAxis(showMaxMin = FALSE)
           p$xAxis(tickFormat ="#!function(d) {return d3.time.format('%Y-%m-%d')(new Date(d * 24 * 60 * 60 * 1000));}!#")
           p
         }
         # If "All" firms are selected, barchart of Top 5 is shown
         else{
           SummaryTab<-aggregate(y1~FIRM,data=plotData,FUN=sum)
           SummaryTab$rank=rank(SummaryTab$y1)
           SummaryTab$rank[SummaryTab$rank>5]<-6
    
           if (length(SummaryTab$rank)>5) {
             #Top 5 firms in terms of y1 are shown
             top5<-SummaryTab[SummaryTab$rank<=5,]
             # other firms are collapsed, shown as 1 entry
    
             others<-aggregate(y1~rank,data=SummaryTab,FUN=sum)  
             others<-others[others$rank==6,]
             others$FIRM<-"Others"
    
             # Create the summarytable to be plotted
             plotData=rbind(top5,others)}
    
           tabledta<-summaryBy(y1~FIRM,data=plotData,FUN=sum,keep.names=TRUE) 
           tabledta<-arrange(tabledta,y1) 
           #   if(is.null(tabledta)) {print("Input is an empty string")}
    
           p <- nPlot(y1 ~ FIRM,data = tabledta, type = 'multiBarHorizontalChart')    
           p$chart(margin=list(left=150))
           p$yAxis(showMaxMin = FALSE)
           p
         }
    
       }
     }) #shinyServer
      ) 
    
Marat Talipov
  • 13,064
  • 5
  • 34
  • 53
  • Thanks very much! I did try it with list but it was not resettable anymore then. – TinaW Jan 03 '15 at 10:12
  • 1
    Did you remove `id=letters[(times %% length(letters)) + 1],` when you replaced `div()` by `list()`? – Marat Talipov Jan 03 '15 at 15:37
  • Yes, I did, but I had removed the "times <- input$reset_input" as well which is needed. I see what you mean now. Thank you! – TinaW Jan 03 '15 at 16:01