0

I'm building a shinyApp using R. Currently i'm using selectinput to select multiple regions/columns by putting multiple=TRUE. But its not working due to some unforeseen reason. It only works when i put ALL in choose region. I believe my problem lies in reactive part of server. I have attached my codes as below. Can someone please look into them and let me know whats wrong with them. Bundle of thanks :)

  **Updated Codes**

  library(shiny)
  library(tidyr)
  library(dplyr)
  library(readr)
  library(DT)

  data_table<-mtcars[,c(2,8,1,3,4,5,9,6,7, 10,11)]

  data_table$disp<-NULL

  names(data_table)[3:10]<- rep(x = 
c('TS_lhr_Wave_1','TS_isb_Wave_2','TS_quta_Wave_1','TS_karach_Wave_2',                                                                            

'NTS_lhr_Wave_1','NTS_isb_Wave_2','NTS_quta_Wave_1','NTS_karach_Wave_2'), 
                              times=1, each=1)   

  # Define UI
  ui <- fluidPage(
  downloadButton('downLoadFilter',"Download the filtered data"),

  selectInput(inputId = "cyl",
              label = "cyl:",
              choices = c("All",
                          unique(as.character(data_table$cyl))),
              selected = "All",
              multiple = TRUE),


  checkboxGroupInput(inputId = "regions", label = "choose region",
                     choices =c("All", "lhr", "isb", "quta", "karach"), 
                     inline = TRUE,   selected = c("All")),


  checkboxGroupInput(inputId = "waves", label = "choose wave",
              choices =c("All", "Wave_1", "Wave_2"), inline = TRUE,
              selected = c("All")),


  DT::dataTableOutput('ex1'))


  # Define Server
  server <- function(input, output) {

  thedata <- reactive({

    if(input$cyl != 'All'){
      data_table<-data_table[data_table$cyl %in%   input$cyl,] }  


    #region
    cols <- c(1, 2)
    # print(input$regions)
    if  ('All' %in% input$regions){
      cols <- 1:ncol(data_table)
    }
    else{
      if  ('lhr' %in% input$regions){
        cols <- c(cols, c(3,7))

      }  
      if  ('isb' %in% input$regions){
        cols <- c(cols, c(4,8))

      }
      if  ('quta'  %in%  input$regions){
        cols <- c(cols, c(5,9))

      }
      if  ('karach'  %in%  input$regions){
        cols <- c(cols, c(6,10))

      }}                

    #else
    data_table<-data_table[,cols, drop=FALSE] 




    #waves
    colss <- c(1, 2)
    # print(input$regions)
    if  ('All' %in% input$waves){
      colss <- 1:ncol(data_table)
    }
    else{
      if  ('Wave_1' %in% input$waves){
        colss <- c(colss, c(3,5,7, 9))
      }  

      if  ('Wave_2'  %in%  input$waves){
        colss <- c(colss, c(4,6, 8, 10))
      }}                

    #else
    data_table<-data_table[,colss, drop=FALSE] 


  }) 


  output$ex1 <- DT::renderDataTable(DT::datatable(filter = 'top',
                                                  escape = FALSE, 
                                                  options = list(                                                                      


scrollX='500px',autoWidth = TRUE),{
                                                      thedata()   }))

  output$downLoadFilter <- downloadHandler(
    filename = function() {
      paste('Filtered data-', Sys.Date(), '.csv', sep = '')  },
    content = function(path){
      write_csv(thedata(),path)   })}

  shinyApp(ui = ui, server = server)

1 Answer 1

1

So your assumption that the error is in the reactive part of the server is true, I found two main problems.

  1. When you select more than one region, then input$regions is a vector of more than one character, which is why when R evaluates the expression input$regions == 'lhr' it compares only the first element of input$regions with 'lhr' and prints out a warning in the console.

  2. In each if statement you are re-assigning the data_table variable, so for example when 'lhr'and 'isb' are chosen then in the first if statement you assign data_table with 4 columns, and then ask for the eighth column when evaluating the second if

Suggestion: during the development of the App you can add print statements as a debugging method, and when you run the App keep your eye on the console to see what is going on. I added one print statement as a comment, if you want un-comment and try it.

thedata <- reactive({

if(input$cyl != 'All'){
  data_table <- data_table[data_table$cyl %in% input$cyl,] }  

#region
all_cols <- names(data_table)
region_cols <- c("cyl", "vs" )
# print(input$regions)
if  ('All' %in% input$regions){
  region_cols <- names(data_table)
}
else{
  if  ('lhr' %in% input$regions){
    region_cols <- c(region_cols, all_cols[grep('lhr', all_cols)])

  }  
  if  ('isb' %in% input$regions){
    region_cols <- c(region_cols, all_cols[grep('isb', all_cols)])

  }
  if  ('quta'  %in%  input$regions){
    region_cols <- c(region_cols, all_cols[grep('quta', all_cols)])

  }
  if  ('karach'  %in%  input$regions){
    region_cols <- c(region_cols, all_cols[grep('karach', all_cols)])

  }}                

#waves
waves_cols <- c("cyl", "vs" )
# print(input$regions)
if  ('All' %in% input$waves){
  waves_cols <- names(data_table)
}
else{
  if  ('Wave_1' %in% input$waves){
    waves_cols <- c(waves_cols, all_cols[grep('Wave_1', all_cols)])
  }  

  if  ('Wave_2'  %in%  input$waves){
    waves_cols <- c(waves_cols, all_cols[grep('Wave_2', all_cols)])
  }}                
# print(intersect(region_cols, waves_cols))
data_table <- data_table[,intersect(region_cols, waves_cols), drop=FALSE]
})

As for the problems on the comment, it seems that I forgot to add an if statement when "All" is chosen (:P), it works now in a way that once "All" is chosen then there is no need to evaluate another if statement.

And the first two columns are now always selected (and not duplicated), regardless if any region is selected or not.

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

5 Comments

Thank you so much mate :) There's a slight problem coming up, when i select 'All', i get nothing. And there's also a repetition of 'cyl' and 'vs'. Can you please look over them. Many thanks:)
Hi mate, I can't thank you enough for the efforts that you put in to make the codes work, your a genius :) I have updated the codes and added checkboxGroupinput instead of selectinput. There's just one last thing left which is: If i choose anything in 'choose region' and 'choose wave' together, i get an error. However if i select 'All' in one, then i get results. Is there any way to sort it out? Thanks
You are again facing the second problem I mentioned in my answer, the data_table variable changes by the time you reach the waves part. You can't ask for column number 7, if you have just 4 columns. The more filters you have the more careful you should be, when dealing with reactive(). It might help if you choose the columns by their names, maybe something like all_cols <- names(data_table); if(......) cols <- all_cols[grep('Wave_1', all_cols)] .
Thanks mate, is it possible to update the codes? Really grateful :)
Can't thank you enough mate. Your simply awesome ! I'm extremely grateful to you :) Best Regards

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.