Shiny Slider Input step by month
This is a solution that I use, but first I'd like to explain the logic:
- As mentioned above,
timeFormat
argument of thesliderInput()
function does not give the required 1-month-step functionality. Instead, it simply formats underlying daily data, so stepping remains intact at a daily increment. sliderInput()
has another argumentstep
which can be used to explicitly define the stepping increment. However, it requires a single integer as an input, and therefore doesn't accept vectors/ranges. Given that months are of different lengths, a single integer is not right to use here. I tried to uselubridate::months(1)
andlubridate::period(1, units = "months")
-- to no avail unfortunately as both were automatically converted to an integer of 30 once rendered by the app, hence monthly increments were not retained.
I found a solution with shinyWidgets::sliderTextInput()
which creates a character slider.
Assuming your dates are stored as yyyy-mm-dd
dates in column Date
of table d
:
sliderTextInput(
inputId = "myID",
label = "myLabel",
choices = as.yearmon(unique(d$Date)),
selected = c(as.yearmon(min(d$Date)), as.yearmon(max(d$Date))),
grid = TRUE,
width = "100%"
)
With this you always step at monthly increments. as.yearmon()
is used so your app shows slider labels in the MMM YYYY
format.
Bear in mind that slider output is a character, so you need to back-transform into date:
as.Date(as.yearmon(input$myID[1]))
for a startas.Date(as.yearmon(input$myID[2]))
for an end
There is a timeFormat
function within the sliderInput
. For more information visit Slider Input Widget.
EDIT:
To get the dates out and use them later on in your analysis, much credit goes to this question First day of the month from a POSIXct date time using lubridate and the function provided by Roland.
rm(list=ls())
library(shiny)
monthStart <- function(x) {
x <- as.POSIXlt(x)
x$mday <- 1
as.Date(x)
}
ui <- basicPage(sliderInput("slider", "Time", min = as.Date("2010-01-01"),max =as.Date("2014-12-01"),value=as.Date("2014-12-01"),timeFormat="%b %Y"),
textOutput("SliderText")
)
server <- shinyServer(function(input, output, session){
sliderMonth <- reactiveValues()
observe({
full.date <- as.POSIXct(input$slider, tz="GMT")
sliderMonth$Month <- as.character(monthStart(full.date))
})
output$SliderText <- renderText({sliderMonth$Month})
})
shinyApp(ui = ui, server = server)