0

I am creating a time series plot based on user input. The application runs without any issue but the plot is not generated. However the same code generates a plot in regular r-script. I cant see the reason why shiny plot will not render.

Test data:

mydata<-structure(list(employee = c("Mary", "rob", 
"smary", "rob", "Abe", "Abe"
), joining_date = structure(c(17869, 17862, 17865, 17848, 
17862, 17848), class = "Date"), batch___A_2019 = c(1, 1, 
1, 1, 1, 0), batches___A_2020 = c(0, 0, 0, 0, 0, 1), batch___B_2020 = c(0, 
0, 0, 0, 0, 0), batch___B_2023 = c(0, 0, 0, 0, 0, 0)), row.names = c(NA, 
6L), class = "data.frame")

R script: This works fine and generates the plot as required

test <- mydata %>%
  mutate(week = week(joining_date)) %>%
  mutate(new_date = format(joining_date, "%m %Y"), year = format(joining_date, "%Y")) %>%
  filter(
    employee == "Mary" | employee == "Abe",
    joining_date >= "2019-01-01" &
      joining_date <= "2023-01-01"
  ) %>%
  group_by(employee,month = lubridate::floor_date(joining_date, 'month')) %>%
  summarize(Total = n(), .groups = "drop") %>%
  complete(month = seq.Date(min(month), max(month), by="month"), employee) %>%
  replace(is.na(.), 0)
  
  
g<-ggplot(test, aes(x = month, y = Total)) +
  geom_line(aes(color = employee)) +
  scale_x_date(date_labels = "%b %Y", date_breaks = "1 month") +
  theme(axis.text.x=element_text(angle=50, hjust=1)) +
  ylab("Total joinee") 

R-shiny (Does not generate the plot)

timeseries <- reactive({
    req(input$employee)
    req(input$test)
    req(input$Dates)
    mydata %>%
      filter(
        employee == input$employee,
        if_any(matches(str_c(
          'batch___', tolower(input$test)
        )), ~
          .x == 1),
        joining_date >= input$Dates[1] &
          joining_date <= input$Dates[2]
      ) %>%
      group_by(month = lubridate::floor_date(joining_date, 'month')) %>%
      summarize(Total = n(), .groups = "drop") %>%
      complete(month = seq.Date(min(month), max(month), by="month"), employee) %>%
      replace(is.na(.), 0)
  })
  
  output$timeseriesplot <- renderPlot({
    ggplot(timeseries()) + 
      geom_line(aes(x = month, y = Total, color=input$test)) +
      scale_x_date(date_labels = "%b %Y", date_breaks = "1 month") +
      theme(axis.text.x=element_text(angle=50, hjust=1)) +
      ylab("Total joinee") 
  })

UI

tabItem(tabName = "Timeseries",
              
              box(
                width = 10,
                
                h2("Time series plot"),
                
                sidebarPanel(
                  selectInput(
                    inputId = "employee",
                    choices = mydata$employee,
                    label = "Search by employee"
                  ),
                  
                  dateRangeInput(
                    "Dates",
                    h5("Select the Dates"),
                    format = "yyyy-mm-dd",
                    start = Sys.Date() - 365
                  ),
                  
                  checkboxGroupInput(
                    inputId = "test",
                    choices = c("A", "B", "C"),
                    selected = c("A", "B", "C"),
                    label = "Select test"
                  )
                ),
                
                mainPanel(plotOutput("timeseriesplot")),
              ),
      ),
akang
  • 566
  • 2
  • 15

1 Answers1

0

I can't confirm my suggestion will work for you as I can't run your application without data. Here is a way I have been able to get graphs to work in shiny. First, I suggest using verbatimTextOutput as one way to get a look at the output of your timeseries reactive to make sure that is not the problem.

Then consider making your plot a reactive and then render the reactive plot.

ts <- reactive({ 

    timeseries <- timeseries()
    
    timeseries %>%
      ggplot() +
      geom_line(aes(x = month, y = Total, color=input$test)) +
      scale_x_date(date_labels = "%b %Y", date_breaks = "1 month") +
      theme(axis.text.x=element_text(angle=50, hjust=1)) +
      ylab("Total joinee") 
})

output$timeseriesplot <- renderPlot({
   ts()
})

stomper
  • 1,252
  • 1
  • 7
  • 12
  • this doesn't work either. – akang Jan 26 '23 at 16:05
  • @akang _"this doesn't work either."_ - I'm confused by this comment since you've accepted the answer (which is a good thing to do if the answer actually answers your question). – Ted Lyngmo Mar 21 '23 at 10:56