如何使用Shiny dateRangeInput阻止用户在开始日期之前设置结束日期

时间:2017-04-25 15:17:11

标签: r date shiny lapply

我有一个闪亮的应用程序,用户选择多个日期范围,我想阻止用户使用lapply函数中的dateRangeInput在开始日期之前设置结束日期。我如何在R中编码?感谢您查看这个。

这是我的代码

       library(shiny)

       ui <-fluidPage(
              checkboxInput("add_trend", "Add Trend(s)"),
              conditionalPanel(condition="input.add_trend === true",
                               numericInput("numoftrends",
                                            label="Number of Linear Trends:",
                             min = 1,
                             max = 10,
                             value = 1,
                             step = 1),
                             uiOutput("num_of_trends"),
                             textOutput("see_ranges")
                ),
             actionButton("submit", "Submit")
        )

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

         output$num_of_trends <- renderUI({
            lapply(1:input$numoftrends, function(i) {
                  dateRangeInput(paste0("date_range_input", i), 
                          paste('Trend Date Range Input', i, ':'),                                                      

                          separator = " - ",
                          format = "yyyy-mm",
                          startview = 'year',
                          start = "2001-01-01",
                          end   = "2020-12-31",
                          min = "2001-01-01",
                          max = "2020-12-31"
                         )
                })  
           })

       trend_list <- reactive({
           out <- list()
          for(i in 1:input$numoftrends) {
           out[[i]] <- input[[paste0("date_range_input", i)]]
            }
          out
       })

        output$see_ranges <- renderPrint({
           print(trend_list())
         })
      }

       shinyApp(ui = ui, server = server)

2 个答案:

答案 0 :(得分:3)

好的,不要不必要地复杂化,我会告诉你一个dateRangeInput()的可能性。

简而言之:将开始日期和结束日期存储在reactiveValue()中,并为其更新设置一些限制。 作为一个例子,如果你的限制被违反,我选择平等地设置开始和结束日期。

  global <- reactiveValues(start = "2001-01-01", end= "2020-12-31")

  observe({
    dates <- input[[paste0("date_range_input", 1)]]
    if(!is.null(dates)){
     if(dates[1] <= global$end){
       global$start <- dates[1]
     }else{
       # date smaller than start value not allowed
       global$start <- global$end
     }

     if(dates[2] >= global$start){
       global$end <- dates[2]
     }else{
       # date greater than end value not allowed
       global$end <- global$start
     }
    }
  })

  output$num_of_trends <- renderUI({
      dateRangeInput(paste0("date_range_input", 1), 
                     paste('Trend Date Range Input', 1, ':'),
                     separator = " - ",
                     format = "yyyy-mm",
                     startview = 'year',
                     start = global$start,
                     end   = global$end,
                     min = "2001-01-01",
                     max = "2020-12-31"
      )
  })

对于包含多个dateRangeInput()的完整版,请参阅以下内容:

library(shiny)

ui <-fluidPage(
  checkboxInput("add_trend", "Add Trend(s)"),
  conditionalPanel(condition="input.add_trend === true",
                   numericInput("numoftrends",
                                label="Number of Linear Trends:",
                                min = 1,
                                max = 10,
                                value = 1,
                                step = 1),
                   uiOutput("num_of_trends"),
                   textOutput("see_ranges")
  ),
  actionButton("submit", "Submit")
)

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

  global <- reactiveValues(start = "2001-01-01", end = "2020-12-31")

  observe({
    global$start <- as.Date(c(global$start, as.Date(rep("2001-01-01", input$numoftrends))))[1:input$numoftrends]
    print(global$start)
    global$end <- as.Date(c(global$end, as.Date(rep("2020-12-31", input$numoftrends))))[1:input$numoftrends]
  })

  observe({
    for(i in 1:input$numoftrends){
      dates <- input[[paste0("date_range_input", i)]]
      if(!is.null(dates)){
        # print(global$end[i])
        if(dates[1] <= global$end[i]){
          global$start[i] <- dates[1]
        }else{
          # date smaller than start value not allowed
          global$start[i] <- global$end[i]
        }
        # print(global$start[i])
        if(dates[2] >= global$start[i]){
          global$end[i] <- dates[2]
        }else{
          # date greater than end value not allowed
          global$end[i] <- global$start[i]
        }
      }
    }
  })

  output$num_of_trends <- renderUI({
    lapply(1:input$numoftrends, function(i) {
      dateRangeInput(paste0("date_range_input", i), 
                     paste('Trend Date Range Input', i, ':'),
                     separator = " - ",
                     format = "yyyy-mm",
                     startview = 'year',
                     start = global$start[i],
                     end   = global$end[i],
                     min = "2001-01-01",
                     max = "2020-12-31"
      )
    })
  })

  trend_list <- reactive({
    out <- list()
    for(i in 1:input$numoftrends) {
      out[[i]] <- input[[paste0("date_range_input", i)]]
    }
    out
  })

  output$see_ranges <- renderPrint({
    print(trend_list())
  })
}

shinyApp(ui = ui, server = server)

答案 1 :(得分:0)

我遇到了这个问题,但是以不同的方式解决了这个问题。我只是假设用户选择了他们想要的日期范围,然后使用max和min。

start<-min(dates)
end<-max(dates)

问题解决了。适用于困惑的用户。