0

I'm trying to create an EDA tab for a Shiny app in R but have already fallen at the first hurdle. In my app, I would like it so that the user can select as many or as few variables from each column in the data to analyse. Here is a mock dataframe and the relevant libraries:-

library(wakefield)#for generating the Status variable
library(dplyr)
library(shiny)
library(shinydashboard)
library(funModeling)
set.seed(1)
Date<-seq(as.Date("2015-01-01"), as.Date("2015-12-31"), by = "1 day")
Date<-sample(rep(Date,each=10),replace = T)


Shop<-r_sample_factor(x = c("Shop_A", "Shop_B", "Shop_C","Shop_D", "Shop_E","Shop_F","Shop_G"), n=length(Date))
Product<-r_sample_factor(x=c("Meat","Fruit","Vegetables","Toiletries","Kitchenware","CleaningProducts"), n=length(Date))
Profit<-sample(1:150, length(Date), replace=TRUE)
Profit


data<-data.frame(Date,Shop,Product,Profit)
levels(data$Shop)
#[1] "Shop_A" "Shop_B" "Shop_C" "Shop_D" "Shop_E" "Shop_F" "Shop_G"
levels(data$Product)
#[1] "Meat"             "Fruit"            "Vegetables"       "Toiletries"       "Kitchenware"      "CleaningProducts"
View(data)

And here is some Shiny code:-

#UI
ui<-fluidPage(
  
  tabPanel("EDA",
           sidebarLayout(
             sidebarPanel(width = 4, 
                          dateRangeInput("eda_daterange","Select date range", format="yyyy-mm-dd",
                                         start=min(data$Date),
                                         end=max(data$Date)),
                          pickerInput("eda_col", "Select variable",
                                      choices = c("Shop",
                                                  "Product")),
                          varSelectInput("level_choice", "Select factors to include",
                                         input$eda_col, multiple = T),
                          
                          actionButton("run_eda", "Run analysis")),
             mainPanel(
               column(width = 8, box("Frequency plot", plotOutput("frequencyplot_eda"), width = "100%")),
               column(width = 8, box("Profit plot", plotOutput("density_eda"), width = "100%"))
               
             )          
             
           )
           
           
  ))

#SERVER
server<-function(input,output,session){
  
  #Calls_new_reac<-reactive(Calls_new)
  variables<-unique(input$eda_col)
  
  
  observeEvent(input$run_eda,{
    
    output$frequencyplot_eda<-renderPlot({
      
      if(input$eda_col=="Shop"){
        
        data<-data%>%
          filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
          filter(variables %in% input$level_choice)
        
        
        freqplot<-freq(data = data, input =input$eda_col )
        
        return(freqplot)
        
      }else{
        
        if(input$eda_col=="Product"){
          
          data<-data%>%
            filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
            filter(variables %in% input$level_choice)
          
          
          freqplot<-freq(data = data, input =input$eda_col )
          
          return(freqplot)
          
        }
        
      }
      
      
      
      
    })
    
    
    output$density_eda<-renderPlot({
      
      if(input$eda_col=="Shop"){
        
        data<-data%>%
          filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
          filter(variables %in% input$level_choice)
        
        densplot<-ggplot(data, aes(x=Profit,group=input$eda_col,colour=input$eda_col))+geom_density()+scale_x_log10()
        
        
        
        return(densplot)
        
      }else{
        
        if(input$eda_col=="Product"){
          
          data<-data%>%
            filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
            filter(variables %in% input$level_choice)
          
          densplot<-ggplot(data, aes(x=Profit,group=input$eda_col,colour=input$eda_col))+geom_density()+scale_x_log10()
          
          
          return(densplot)
          
        }
        
      }
      
    })
    
  })#end of observe event
  
}


shinyApp(ui, server)

The first pickerInput allows the user to select a column to analyse. The varSelectInput was my attempt to allow the user to pick which variable from the selected column to analyse. However, the error message (caused by this):-

varSelectInput("level_choice", "Select factors to include",
                                         input$eda_col, multiple = T)

is this:-

Error in is.data.frame(x) : object 'input' not found

My Shiny expertise is not great as you can see. How can I tidy this up so it would allow me to pick columns and pick the relevant variables that I want to analyse?

1 Answer 1

3

One way to do it is to use renderUI() to select the factors. Try this

data<-data.frame(Date,Shop,Product,Profit)

ui<-fluidPage(
  
  tabPanel("EDA",
           sidebarLayout(
             sidebarPanel(width = 4, 
                          dateRangeInput("eda_daterange","Select date range", format="yyyy-mm-dd",
                                         start=min(data$Date),
                                         end=max(data$Date)),
                          pickerInput("eda_col", "Select variable",
                                      choices = c("Shop", "Product")),
                          uiOutput("varselect"),
                          
                          actionButton("run_eda", "Run analysis")),
             mainPanel(
               # DTOutput("t1"),
               column(width = 8, box("Frequency plot", plotOutput("frequencyplot_eda"), width = "100%")),
               column(width = 8, box("Profit plot", plotOutput("density_eda"), width = "100%"))
               
             )          
             
           )
           
           
  ))

#SERVER
server<-function(input,output,session){
  
  output$varselect <- renderUI({
    vars <- data[[as.name(input$eda_col)]]
    selectInput("level_choice", "Select factors to include", unique(vars) , multiple = T)
  })
  
  output$t1 <- renderDT({
    req(input$level_choice)
    data %>%
      filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2]) %>%
      filter(.data[[input$eda_col]] %in% input$level_choice)
    
  })
  
  observeEvent(input$run_eda,{
    req(input$level_choice)
    
    output$frequencyplot_eda<-renderPlot({
      
      data1<-data%>%
        filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
        filter(.data[[input$eda_col]] %in% input$level_choice)
      
      freqplot<-freq(data = data1, input = data1[[input$eda_col]] )
      
      return(freqplot)
      
    })
    
    output$density_eda<-renderPlot({
      
      data2 <- data %>%
        filter(Date>=input$eda_daterange[1] & Date<=input$eda_daterange[2])%>%
        filter(.data[[input$eda_col]] %in% input$level_choice)
      
      densplot<-ggplot(data2, aes(x=Profit,group=.data[[input$eda_col]],colour=input$eda_col))+
                  geom_density()+scale_x_log10()
      
      return(densplot)
      
    })
    
  })#end of observe event
  
}


shinyApp(ui, server)

output

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

2 Comments

this is great, thank you! I have one additional query. How would I colour each factor? For instance, in the density plot in the picture you have above, we have 2 variables. How could I code them in a different colour each using ggplot (usual colour argument in aes is not working)?
actually nevermind, I wrap them in this: colour=.data[[input$eda_col]]. Thanks again!

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.