Search code examples
rshinytidyverse

Filter by date from sliderTextInput in Shiny


I'm working on a Shiny app where a tibble is filtered by a range of dates selected from a shinyWidgets::sliderTextInput object. The dates are turned into yearmon format for the interactive object, because it's monthly data, then turned back into Date objects for filtering. The code works fine outside of Shiny, but when placed in Shiny I get the error Caused by error in charToDate(): character string is not in a standard unambiguous format

Setup:

library(shiny)
library(tidyverse)
library(zoo)

df <- tibble(a = 1:3, 
             date = as.Date(c("2007-1-1", "2007-2-1", "2007-3-1"))
             )

The line of filter code works fine outside of Shiny:

df %>% filter(date >= as.Date(as.yearmon("2007-2-1"))) # filter line

The same code raises an error when used in Shiny:

ui <- fluidPage(
  shinyWidgets::sliderTextInput("select_dates", NULL,
                                choices = as.yearmon(df$date),
                                selected = as.yearmon(c("2007-1-1", 
                                                        "2007-2-1")),
                                animate = TRUE,
                                grid = FALSE,
                                dragRange = TRUE),
  tableOutput("show_dates")
)

server <- function(input, output, session) {
  output$show_dates <- renderTable({
    df %>% filter(date >= as.Date(input$select_dates[1])) # filter line
  })
}

shinyApp(ui = ui, server = server)

I've been unable to figure out what's happening here. I'm not using a dateRangeInput object because I don't want the day to be selected. This question has the same error, but doesn't seem to be the same issue - I'm clearly turning the selection into a date object in order to filter a date column.


Solution

  • Change the server part to this: I would suggest to split transforming to Date and yearmon and filtering:

    library(shiny)
    library(tidyverse)
    library(zoo)
    
    
    df <- tibble(a = 1:3, 
                 date = as.Date(c("2007-1-1", "2007-2-1", "2007-3-1"))
    )
      
    ui <- fluidPage(
        shinyWidgets::sliderTextInput("select_dates", NULL,
                                      choices = as.yearmon(df$date),
                                      selected = as.yearmon(c("2007-1-1", 
                                                              "2007-2-1")),
                                      animate = TRUE,
                                      grid = FALSE,
                                      dragRange = TRUE),
        tableOutput("show_dates")
      )
    
    server <- function(input, output, session) {
      output$show_dates <- renderTable({
        
        selected_dates <- as.Date(as.yearmon(input$select_dates), frac = 1)
        df_filtered <- df %>%
          filter(date >= selected_dates[1] & date <= selected_dates[2])
        df_filtered
      })
    }
    
    shinyApp(ui = ui, server = server)
    

    enter image description here