0

I am new to R and Shiny and have a problem that I have not been able to solve for hours.

I have a dataset from which I display the daily consumption of coffee on a dashboard, which works very well. The plot is a ggplot geom_line chart.

But now I want to be able to change the time period with two sliders. The sliders I have also managed to do, but the plot does not change when the slider is moved.

I also suspect that I have an error with the date format.

What am I doing wrong? Thanks for the help

RawData Dataset

library(shiny)
library(dplyr)
library(data.table)
library(ggplot2)

ui <- shinyUI(fluidPage(

  # Application title
  titlePanel("Coffee consumption"),

  # Sidebar with a slider input for the number of bins
  sidebarLayout(
    sidebarPanel(
      sliderInput("DatesMerge",
                  "Dates:",
                  min = as.Date("2018-01-22","%Y-%m-%d"),
                  max = as.Date("2020-04-04","%Y-%m-%d"),
                  value= c(as.Date("2018-01-22","%Y-%m-%d"),as.Date("2020-04-04","%Y-%m-%d")),
                  timeFormat="%Y-%m-%d")
    ),
    mainPanel(

      plotOutput("plot_daycount"),
      tableOutput("structure"),
      tableOutput("rawdata"),
      tableOutput("dayconsumption")) 

  )
)
)


# RawData import

coffeedata = fread("C:/temp/ProductList.csv")

setDF(coffeedata)

coffeedata$Date = as.Date(coffeedata$Date, "%d.%m.%Y")

# Products a day counter
countcoffee <- function(timeStamps) {
  Dates <- as.Date(strftime(coffeedata$Date, "%Y-%m-%d"))
  allDates <- seq(from = min(Dates), to = max(Dates), by = "day")
  coffee.count <- sapply(allDates, FUN = function(X) sum(Dates == X))
  data.frame(day = allDates, coffee.count = coffee.count)}

# Making a DF with day consumption
daylicounter = countcoffee(df$coffee.date)


server <- shinyServer(function(input, output) {


  output$structure = renderPrint({
    str(coffeedata)
  })

  # Raw Data
  output$rawdata = renderTable({
    head(coffeedata)
  })

  output$dayconsumption = renderTable({
    head(daylicounter)
  })


  # GGPLOT2
  output$plot_daycount = renderPlot({

    DatesMerge = input$DatesMerge

    ggplot(daylicounter[daylicounter == DatesMerge], aes(daylicounter$day, daylicounter$coffee.count)) + 
           geom_line(color = "orange", size = 1) 
           scale_x_date(breaks = "3 month", 
                       date_labels = "%d-%m-%Y")


# Try outs    
#   ggplot(daylicounter[month(day) == month(DatesMerge)], mapping = aes(day = day)) + 
#      geom_line(color = "orange", size = 1) 
#      scale_x_date(breaks = "3 month", 
#                  date_labels = "%d-%m-%Y")
  })

})

shinyApp(ui, server)


I appreciate your help

Skruff
  • 75
  • 1
  • 8
  • If you have additional comments/questions, feel free to use comments section (or post new question on SO) rather than adding an answer. See my edited answer in regards to your last question. Good luck! – Ben Apr 09 '20 at 13:02

2 Answers2

1

As noted by @Kevin, you need to use input$DatesMerge[1] and input$DatesMerge[2] when subsetting your data. For clarity, this can be done in a separate step. Try something like this in your server:

output$plot_daycount = renderPlot({
  DatesMerge <- as.Date(input$DatesMerge, format = "%Y-%m-%d")
  sub_data <- subset(daylicounter, day >= DatesMerge[1] & day <= DatesMerge[2])
  ggplot(sub_data, aes(x = day, y = coffee.count)) + 
    geom_line(color = "orange", size = 1) +
    scale_x_date(breaks = "3 month", date_labels = "%d-%m-%Y")
})

Edit Additional question from OP was asked:

Why does my date format look normal with str(coffeedata) but with head(coffeedata) the date is just a number?

renderTable uses xtable which may have trouble with dates. You can get your dates to display correctly by converting to character first (one option):

output$rawdata = renderTable({
  coffeedata$Date <- as.character(coffeedata$Date)
  head(coffeedata)
})

output$dayconsumption = renderTable({
  daylicounter$day <- as.character(daylicounter$day)
  head(daylicounter)
})

See other questions on this topic:

as.Date returns number when working with Shiny

R shiny different output between renderTable and renderDataTable

Ben
  • 28,684
  • 5
  • 23
  • 45
0

Welcome to R and Shiny, you are off to a great start. Few things:

  1. I don't recommend you using = in shiny, majority of the cases you want to use <-
  2. To simplify code, no reason to add a variable like DatesMerge. It adds no value (at least in the code above)
  3. For a dual slider, you need to tell shiny which end to pick. input$DatesMerge doesn't mean anything but input$DatesMerge[1] does.
  4. When asking for help, it is always better to add a subset of data within the code itself. You tend to get more help and it is easier to run for the person trying to help (like me I was too lazy to download the file and place it in a folder so I didn't run it)

You need to account for a range of dates in your slider when subsetting the data; you also for the , when subsetting the data.

ggplot(daylicounter[daylicounter %in% input$DatesMerge[1]:input$DatesMerge[2],], aes(daylicounter$day, daylicounter$coffee.count)) + 
       geom_line(color = "orange", size = 1) +
       scale_x_date(breaks = "3 month", 
                   date_labels = "%d-%m-%Y")
Kevin
  • 1,974
  • 1
  • 19
  • 51