R Shiny:在动态情况下有条件地更新可能的用户输入选择

时间:2019-04-01 15:09:02

标签: r shiny conditional

我创建了一个微型的Shiny应用程序,其中询问用户他/她想剪切给定日期向量(在2到4之间)的周期。然后,要求用户在每个时间段(最后一个时间段除外)选择该时间段的最后日期。

该应用程序正在运行,但是,有些愚蠢的用户可能选择的结束日期不是递增的,例如,时间段1的选定结束日期可能晚于时间段2的选定结束日期。等

换句话说,我希望在定义cutpoint2仅包含cutpoint1日期之后的日期等时使用户可以使用选择(日期),因此,如果用户选择“ 2006-12-31”作为时间段1的结束日期,我希望时间段2的用户输入框可用的日期在该日期之后开始。

但是,我不确定在这种超动态情况下是否有可能,因为首先,我第一次创建这些切入点输入-当甚至根本没有询问用户有关日期的信息时,所以我无法使他们真正相互依赖。然后,我要求用户定义切入点-然后,我希望该动态效果能够发挥作用。

感谢您的建议!

library(shiny)

ui = shinyUI(fluidPage(

  titlePanel("Defining time periods"),
  sidebarLayout(
    sidebarPanel(
      numericInput("num_periodsnr", label = "Desired number of time periods?",
                   min = 2, max = 4, value = 2),
      uiOutput("period_cutpoints"),
      actionButton("submit", "Update time periods")
    ),
    mainPanel(                       # Just shows what was selected
      textOutput("nr_of_periods"),
      textOutput("end_dates")
    )
  )
))

server = shinyServer(function(input, output, session) {

  library(lubridate)
  output$nr_of_periods <- renderPrint(input$num_periodsnr)

  # Dates string to select dates from:
  dates <- seq(ymd('2016-01-02'), ymd('2017-12-31'), by = '1 week')

  output$period_cutpoints <- renderUI({
    req(input$num_periodsnr)
    lapply(1:(input$num_periodsnr - 1), function(i) {
      selectInput(inputId = paste0("cutpoint", i), 
                  label = paste0("Select the last date of Time Period ", i, ":"),
                  choices = dates)
    })
  })

  dates_chosen <- reactiveValues(x = NULL)
  observeEvent(input$submit, {
    dates_chosen$x <- list()
    lapply(1:(input$num_periodsnr - 1), function(i) { 
      dates_chosen$x[[i]] <- input[[paste0("cutpoint", i)]]
    })
  })

  output$end_dates <- renderText({paste(as.character(dates_chosen$x), collapse = ", ")})
})

shinyApp(ui = ui, server = server)

1 个答案:

答案 0 :(得分:1)

将此插入服务器功能:

observe({
    if(input$num_periodsnr > 2){
      for(i in 2:(input$num_periodsnr - 1)) {
        updateSelectInput(session, paste0("cutpoint", i), choices = dates[dates > input[[paste0("cutpoint", i-1)]]])
      }
    }
})

由于您希望在增加周期数时进行新的selectInput,因此(无意中)您会(无意地)覆盖以前的结果,并在用户离开例如3至4个切入点周期。