0

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)

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer. There is one more question about subseting. Fuction like allows the partial matching. Is there another way to do partial match?
Generally %in% works quite well and is widely applicable. Alternatively you can look into match or subset. There are also a number of versions out there within packages such as ddplyr, data.table, sqldf that would do the subsetting quote well, I would recommend using data.table package as in some cases it outperforms others and offers bread functionality in data table manipulation. Don't spend too much time on sub-setting unless you are doing very computationally intensive tasks then its better to work with lists and matrices oppose to data frames
I have found one more problem in here: df2 <- df[df$Category %in% input$Category,] df2 <- (data.table(df))[like(df$Category,input$Category)] The first line works good. However, what I like to do is to filter partial matches. For example, when I select Midfielder filter must include Midfielder / Striker. The like function does the job, but I get an error while the app is loading. Any suggestions?

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.