AK47
AK47

Reputation: 1328

ShinyApp errors: selectInput, data-subsetting

I am creating shiny app. My goal is to visualize some data slices depending on the input.I am quite happy with the result. However, my app has a few bugs while the app is loading. Before ploting the graph and visualizing inputs it shows some errors on screen (you can lauch the app and see the problem).

I believe, the first problem is with data filtering. I can't figure out how to deal with it and what is the problem. May I need to use other method or maybe other package? (see the output$Brand).

Error in grep(pattern, levels(vector)) : invalid 'pattern' argument

The second error comes when I am creating selectInput. I'd like to visualize all the brands of the specific category in one plot and to have an option to filter data by brand. However, my method is not working well. Any suggestions? (see the output$Brand).

Error in if (input$Brand == "All") { : argument is of length zero

Also, I enclose the code, which you can generate.

May you have any more suggestions how to simplify the code?

Thanks for the help!

library(shiny)
library(shinydashboard)
library(data.table)
library(ggplot2)
library(grid)
library(scales)
library(ggthemes)



# Header -----------------------------------------------------------

header <- dashboardHeader(title="Dashboard")

# Sidebar --------------------------------------------------------------

sm <- sidebarMenu(
  menuItem(
    text="Graph1",
    tabName="Graph1",
    icon=icon("home")
    )
)

sidebar <- dashboardSidebar(sm)

# Body --------------------------------------------------

body <- dashboardBody(

# Layout  --------------------------------------------  

tabItems(
 tabItem(
  tabName="Graph1",

  fluidPage(
         fluidRow(

      box(
        title = "Inputs", status = "warning", width = 2, solidHeader = TRUE,

        uiOutput("Year"),
        uiOutput("Category"),
        uiOutput("Brand"),
        sliderInput("Finalas.Range", "Months:",
                    min = 1, max = 12, value = c(1,12)) 

         ),

      box(
        title = "Season", width = 10, status = "info", solidHeader = TRUE,

        plotOutput("Graph1")

   )  
  )
)
)
)
)

# Setup Shiny app UI components -------------------------------------------

ui <- dashboardPage(header, sidebar, body, skin="black")

# Setup Shiny app back-end components -------------------------------------

server <- function(input, output) {

# Generate data --------------------------------------

  set.seed(1992)
  n=99
  Year <- sample(2013:2015, n, replace = TRUE, prob = NULL)
  Month <- sample(1:12, n, replace = TRUE, prob = NULL)
  Category <- sample(c("Car", "Bus", "Bike"), n, replace = TRUE, prob = NULL)
  Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
  Brand <- paste0(Brand, sample(1:14, n, replace = TRUE, prob = NULL))
  USD <- abs(rnorm(n))*100

  df <- data.frame(Year, Month, Category, Brand, USD)



  # Inputs --------------------------------------
  output$Year <- renderUI({
  selectInput("Year", 
            "Year:", 
            c(unique(as.character(df$Year))), selected = "2015")
  })


  output$Category <- renderUI({
    selectInput("Category", "Choose category:", 
            choices = c("Car","Bus", "Bike" ))
  })


  output$Brand <- renderUI({
    df2 <- (data.table(df))[like(df$Category,input$Category)]
    selectInput("Brand", 
            "Brand:", 
            c("All", unique(as.character(df2$Brand)))) 
  })


  # Plot --------------------------------

  output$Graph1 <- renderPlot({

df <- data.table(df)

      if (input$Brand == "All") {

        df <- df[like(df$Year, input$Year)]   
        df <- df[like(df$Category,input$Category)] 

        ggplot(df, aes(x=factor(Month,levels=1:12), y=USD, fill=Brand))+
          geom_bar(stat='identity')+
          scale_x_discrete('Month', breaks=factor(1:12), drop=FALSE)+
          scale_fill_gdocs(guide = guide_legend(title = "Brand"))

      } else {


        df <- df[like(df$Year, input$Year)]   
        df <- df[like(df$Category,input$Category)] 
        df <- df[which(df$Brand == input$Brand),]

        validate(
          need(sum(df$USD)>0, paste(input$Brand, "was inactive in Year:",input$Year))
          )

        ggplot(df, aes(x=factor(Month,levels=1:12), y=USD, fill=Brand))+
          geom_bar(stat='identity')+
          scale_x_discrete('Month', breaks=factor(1:12), drop=FALSE) 
      }

  })

# ----------------------------------------------------------------------------- 

}

# Render Shiny app --------------------------------------------------------

shinyApp(ui, server)

Upvotes: 0

Views: 361

Answers (1)

Pork Chop
Pork Chop

Reputation: 29387

The following should eliminate these errors: for #1 the function like in datatable gives out the error so I changed it to %in% instead. and for #2 you have a null as a default so take care of that with an if statement

rm(list = ls())
library(shiny)
library(shinydashboard)
library(data.table)
library(ggplot2)
library(grid)
library(scales)
library(ggthemes)


# Header -----------------------------------------------------------

header <- dashboardHeader(title="Dashboard")

# Sidebar --------------------------------------------------------------

sm <- sidebarMenu(
  menuItem(
    text="Graph1",
    tabName="Graph1",
    icon=icon("home")
  )
)

sidebar <- dashboardSidebar(sm)

# Body --------------------------------------------------

body <- dashboardBody(

  # Layout  --------------------------------------------  

  tabItems(
    tabItem(
      tabName="Graph1",

      fluidPage(
        fluidRow(

          box(
            title = "Inputs", status = "warning", width = 2, solidHeader = TRUE,

            uiOutput("Year"),
            uiOutput("Category"),
            uiOutput("Brand"),
            sliderInput("Finalas.Range", "Months:",
                        min = 1, max = 12, value = c(1,12)) 

          ),

          box(
            title = "Season", width = 10, status = "info", solidHeader = TRUE,

            plotOutput("Graph1")

          )  
        )
      )
    )
  )
)

# Setup Shiny app UI components -------------------------------------------

ui <- dashboardPage(header, sidebar, body, skin="black")

# Setup Shiny app back-end components -------------------------------------

server <- function(input, output) {

  # Generate data --------------------------------------

  set.seed(1992)
  n=99
  Year <- sample(2013:2015, n, replace = TRUE, prob = NULL)
  Month <- sample(1:12, n, replace = TRUE, prob = NULL)
  Category <- sample(c("Car", "Bus", "Bike"), n, replace = TRUE, prob = NULL)
  Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
  Brand <- paste0(Brand, sample(1:14, n, replace = TRUE, prob = NULL))
  USD <- abs(rnorm(n))*100

  df <- data.frame(Year, Month, Category, Brand, USD)



  # Inputs --------------------------------------
  output$Year <- renderUI({
    selectInput("Year", 
                "Year:", 
                c(unique(as.character(df$Year))), selected = "2015")
  })


  output$Category <- renderUI({
    selectInput("Category", "Choose category:", 
                choices = c("Car","Bus", "Bike" ))
  })


  output$Brand <- renderUI({


    # first error
    #df2 <- (data.table(df))[like(df$Category,input$Category)]

    df2 <- df[df$Category %in% input$Category,]


    selectInput("Brand", 
                "Brand:", 
                c("All", unique(as.character(df2$Brand)))) 
  })


  # Plot --------------------------------

  output$Graph1 <- renderPlot({

    df <- data.table(df)

    if(is.null(input$Brand) || is.na(input$Brand)){return()}

    else if (input$Brand == "All") {

      df <- df[like(df$Year, input$Year)]   
      df <- df[like(df$Category,input$Category)] 

      ggplot(df, aes(x=factor(Month,levels=1:12), y=USD, fill=Brand))+
        geom_bar(stat='identity')+
        scale_x_discrete('Month', breaks=factor(1:12), drop=FALSE)+
        scale_fill_gdocs(guide = guide_legend(title = "Brand"))

    } else {


      df <- df[like(df$Year, input$Year)]   
      df <- df[like(df$Category,input$Category)] 
      df <- df[which(df$Brand == input$Brand),]

      validate(
        need(sum(df$USD)>0, paste(input$Brand, "was inactive in Year:",input$Year))
      )

      ggplot(df, aes(x=factor(Month,levels=1:12), y=USD, fill=Brand))+
        geom_bar(stat='identity')+
        scale_x_discrete('Month', breaks=factor(1:12), drop=FALSE) 
    }

  })

  # ----------------------------------------------------------------------------- 

}

# Render Shiny app --------------------------------------------------------

shinyApp(ui, server)

Upvotes: 2

Related Questions