Search code examples
rplotshinyshiny-server

Barplot in Shiny is showing 1 bar too few and strange skinny lines


I have created a barplot using data which is read from a csv file.

Initially created a filter function to filter data from RGui and applied it in a barplot(). It was able to filter out the list of data and displayed 5 bars which is expected.

Adding the same barplot in shiny (several code changes), the barplot will always display 1 less bar and also display the rest of the data in very thin bars.

(See image below)

Server.R

slt <- read.csv("data/slt_inc.csv")
#extract only the number column
slt_vec <- c(slt$num_of_inc)
#extract only the date column
slt_date <- c(slt$date)

output$incidentPlot <- renderPlot({barplot(slt_vec, names.arg=slt$date, main="SLT Incidents", xlab="Date", ylab="# of Incidents", col="green", as.Date(slt_date, origin="2016-10-24") >= input$dateRange[1] & as.Date(slt_date, origin="2016-10-24") <= input$dateRange[2])})

ui.R

dateRangeInput("dateRange", "Date Selection: ", start="2016-10-24", end=NULL, format="yyyy-mm-dd", min="2016-10-24", language = "en", width="100%"),
fluidRow(column(6, verbatimTextOutput("date"))),

Any ideas, of how to resolve this issue?

Also another issue which may be relevant.

using another date range Dec 28 - Dec 30

CSV file data

  • 2016-12-28,wednesday,2
  • 2016-12-29,thursday,1
  • 2016-12-30,friday,1

It should display at least 2 bars or expected 3, but once i filter for Dec 28 to Dec 30 nothing shows up.

enter image description here


Solution

  • Ok, two things. First the funny skinny lines are because your logical vector that you intended to use to subset the data is actually being interpreted as barwidths (the second unnamed parameter). For example this barplot function call:

    barplot( c(5,4,6,3,1,2,4), c(T,T,F,F,F,F,F) )
    

    Gets you this plot:

    enter image description here

    See ?barplot for more info.

    Secondly I faked your data and put together a small example to show you how I would approach this task:

    library(shiny)
    
    u <- shinyUI(fluidPage(fluidRow(
          dateRangeInput("dateRange","Date Selection: ",
                          start = "2016-10-24",end = NULL,
                         format = "yyyy-mm-dd",min = "2016-10-24",
                         language = "en",width = "100%"),
          fluidRow(column(6,verbatimTextOutput("date"))),
          plotOutput('incidentPlot')  
    )))
    
    s <- shinyServer(function(input,output) {
    
      # fake up the data
      dd1 <- c(24,25,26,28,28)
      sltval1 <- c(5,1,6,7,2)
      dayval1 <- as.Date(sprintf("2016-10-%2.2d",dd1))   
      dd2 <- c(7,8,9,12,13,14,15,16,19,20,21,22,23,26,27,28,29,30)
      sltval2 <- c(6,5,1,3,6,6,1,2,3,6,4,1,0,0,1,2,1,1)
      dayval2 <- as.Date(sprintf("2016-12-%2.2d",dd2))
      slt <- data.frame(date = c(dayval1,dayval2),num_of_inc = c(sltval1,sltval2))
      slt$dow <- weekdays(slt$date)
      # end of data fakery
    
      output$date <- renderPrint({ print(input$dateRange) })
    
      output$incidentPlot <- renderPlot({
        dmin <- as.Date(input$dateRange[1])
        dmax <- as.Date(input$dateRange[2])
        bdf <- slt[ dmin<= slt$date & slt$date <= dmax, ]
        barplot(bdf$num_of_inc,names.arg = bdf$date, col = "green",
                main="SLT Incidents",xlab="Date",ylab="# of Incidents")
        })
    })
    shinyApp(ui = u,server = s)
    

    enter image description here

    And finally, you probably need more understanding of how to use and subset dataframes and vectors if you are to easily write effective R code. R's approach to data manipulation and subsetting is too unlike other languages to expect that you can pick it up without a bit of study.

    For example I would recommend carefully reading at least some of the online book Advanced-R, especially the two beginning chapters on Data Structures and Subsetting - or something equivalent.