compare dates in a conditionalPanel using R Shiny

Viewed 379

I am using conditionalPanel in the ui.R file. I want to compare if the given date in a selectinput before or after a certain date (30.09.2019) is.

my selectInput looks like:

selectInput(inputId = 'date',
            label = 'Stichtag:',
            choices = sub("([0-9]{4}).([0-9]{2}).([0-9]{2})", "\\3.\\2.\\1",sort(as.Date(
 sub("([0-9]{2})([0-9]{2})([0-9]{4})KRB.csv", "\\1.\\2.\\3",
 list.files('./data', full.names = FALSE,
 recursive = FALSE)),format="%d.%m.%Y"),decreasing = T)
   )),

and my conditionalPanel

conditionalPanel(
     #condition = " input.date == '30.09.2019'",  #(this works)                        
     condition="Date.parse(input.date)>Date.parse(30.08.2019)", #(it dose not work)
     ## select the variables and order
               pickerInput(
                   inputId = "assetclass",
                   label = "Assetklassen:",
                   choices = c(sort(unique(bestand.name))),    
                   sort(unique(bestand.name)),  
                   multiple = T
               ) ),

in the code above you see 2 conditions. The first one

 condition = " input.date == '30.09.2019'"

works but is not the general smart solution because I will every 3 months I will have an additional date. Therefore I am looking for a general solution like

condition="Date.parse(input.date)>Date.parse(30.08.2019)"

I know that I have to use Js. But it dose not work!

Addendum: I tried to see the format of the input date in server.R

Browse[2]> input$date
[1] "30.09.2019"

so I have probably to transforme the strings in dates befor I compare them in JS!? I tried just for fun the following statement:

 condition= "new Date('2013-05-23') > new Date('2013-05-24')",

however, it dose not work!

2 Answers

I know that you are asking about how to compare dates in conditionalPanel, but whatever you are trying to do, it will be much easier using renderUI on the server side.

From your question I assume that you have some quarterly reports running and that with the changes of the quarter you want to display different filters / selectInputs.

Below I show a toy example which checks if the chosen input$date is equal to end date of last quarter (round_date(Sys.Date(), "quarter") - days(1))).

Note, that I added library calls to stringr and lubridate.

I further made up a character vector of csv files names, since I cannot reproduce the code you provide.

library("shiny")
library("shinyWidgets")
library("lubridate")
library("stringr")

# made up character vector of csv file names
date_vec <- c("30092019KRB.csv",
              "31082019KRB.csv",
              "31072019KRB.csv",
              "30062019KRB.csv",
              "31052019KRB.csv",
              "30042019KRB.csv")

shinyApp(

  ui = fluidPage( # user interface

    sidebarLayout( # layout with Sidebar

      sidebarPanel( # input sidebarPanel

        selectInput(inputId = 'date',
                    label = 'Stichtag:',
                    choices = sub("([0-9]{4}).([0-9]{2}).([0-9]{2})",
                                  "\\3.\\2.\\1",
                                  sort(as.Date(sub("([0-9]{2})([0-9]{2})([0-9]{4})KRB.csv",
                                                   "\\1.\\2.\\3",
                                       # below date_vec replaces your list.files() call
                                                   date_vec), 
                                               format="%d.%m.%Y"),
                                       decreasing = T)
                    )
        ) ,

        uiOutput("classes")

      ), # closes sidebarPanel

      mainPanel( # Output in mainPabel


      ) # closes mainPanel

    ) # closes sidebarLayout

  ), # closes fluidPage

  server = function(input, output) {

    output$classes <- renderUI({

      # example condition: if input$date is equal to the date of the actual quarter minus 1 day then...
      if(dmy(str_remove(input$date, "KRB.csv")) == (round_date(Sys.Date(), "quarter") - days(1))) {

      # use show this pickerInput ....
      pickerInput(
        inputId = "assetclass",
        label = "Assetklassen:",
        choices = c("class a", "class b", "class c"),
        multiple = T
      )

      # otherwise show this pickerInput ...
      } else {

        pickerInput(
          inputId = "equity",
          label = "Equity classes:",
          choices = c("class d", "class e", "class f"),
          multiple = T
        )  

      }

    })


  }

) # closes shinyApp

If you prefer conditionalPanel you can build on the approach from Udit (below), but instead writing a JS function you could bring your input vector into the right format and use it as is.

However, if you use the input vector later on the server side you would need to bring it into the old format with some string manipulation.

library("shiny")
library("shinyWidgets")

# made up character vector of csv file names
date_vec <- c("30092019KRB.csv",
              "31082019KRB.csv",
              "31072019KRB.csv",
              "30062019KRB.csv",
              "31052019KRB.csv",
              "30042019KRB.csv")

choice_vec <- gsub("[-]",
                   "/",
                   sort(as.Date(sub("([0-9]{2})([0-9]{2})([0-9]{4})KRB.csv",
                                    "\\3.\\2.\\1",
                                    # below date_vec replaces your list.files() call
                                    date_vec), 
                                format="%Y.%m.%d"),
                        decreasing = T)
)



names(choice_vec) <- sub("([0-9]{4}).([0-9]{2}).([0-9]{2})",
                         "\\3.\\2.\\1",
                         sort(as.Date(sub("([0-9]{2})([0-9]{2})([0-9]{4})KRB.csv",
                                          "\\1.\\2.\\3",
                                          # below date_vec replaces your list.files() call
                                          date_vec), 
                                      format="%d.%m.%Y"),
                              decreasing = T)
)

shinyApp(

  ui = fluidPage( # user interface

    sidebarLayout( # layout with Sidebar

      sidebarPanel( # input sidebarPanel

        selectInput(inputId = 'date',
                    label = 'Stichtag:',
                    choices = choice_vec
        ) ,

        conditionalPanel(
          condition = "new Date('2019/09/30') > new Date(input.date)",
          pickerInput(
            inputId = "assetclass",
            label = "Asset casses:",
            choices = c("class a", "class b", "class c"),
            multiple = T
          )
        )

      ), # closes sidebarPanel

      mainPanel( # Output in mainPabel

      ) # closes mainPanel

    ) # closes sidebarLayout

  ), # closes fluidPage

  server = function(input, output) {



  }

) # closes shinyApp

this is how you can convert your date to a valid date, you might consider making a function out of it:

var date = "30.09.2019"
var arr = date.split(".")

var array = Array.from(arr);
array.reverse();
array.join("/"); // this will return a valid date 

Try Comparing like following

new Date(input.date) > new Date("2019/09/30")

following is the function which would give you converted Date

function convertDate(data){
var arr = data.split(".")

var array = Array.from(arr);
var converted = array.reverse().join("/")

return converted;
}

Now where you are comparing just use you normal comparison method

  new Date() > new Date(convertDate("30.09.2019"))

and it will return if it is true or not.

I hope this would help you.

Related