在下面的示例中(暂时忽略var Select 逻辑),是否可以使用updateSliderInput来更改年份滑块类型,如果是input$slider_type == 'one'(缺省值),则只接受一个值,如果是input$slider_type == 'two',则是一个值范围?

如果不是,是否需要uiOutput%/renderUI%的方法,或者是否有第三种方法?

library(tidyverse)
library(shiny)


dta <- tibble(
  var =
    c(
      rep("A", 10),
      rep("B", 3),
      rep("C", 5)
    ),
  year = c(
    1984:1993,
    1987:1989,
    1990:1994
  )
) %>%
  mutate(
    val = runif(n())
  )

ui <- fluidPage(

    titlePanel("Dynamic year slider"),

    sidebarLayout(
        sidebarPanel(
            selectInput(
              "var_select", "Select variable",
              choices = unique(dta$var)[1],
              selected = unique(dta$var)[1]
            ),
            selectInput("slider_type", "Select slider type",
                        choices = c("One value" = "one", "Two values" = "more"),
                        selected = "one"

                        ),
            sliderInput("year_select",
                        "Select year:",

                        min = min(subset(dta, var == unique(dta$var)[1])$year),
                        max = max(subset(dta, var == unique(dta$var)[1])$year),
                        value = min(subset(dta, var == unique(dta$var)[1])$year),
                        step = 1,
                        sep = ''

            )
        ),

        mainPanel(
           tableOutput("table_output")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
  current_var <- reactive(input$var_select)
  current_slider_type <- reactive(input$slider_type)
  current_year_value  <- reactive(input$year_select)

  observeEvent(input$var_select, {
    message("The selected var is ", current_var())
    freezeReactiveValue(input, "year_select")
    updateSliderInput(inputId = "year_select",
                      min = min(subset(dta, var == current_var())$year),
                      max = max(subset(dta, var == current_var())$year)

    )
  })

  observeEvent(input$slider_type, {
    this_slider_type <- current_slider_type()
    message("The current slider type is ", this_slider_type)
    if (this_slider_type == "more"){
      message("current_slider_type is more")

      updateSliderInput(inputId = "year_select",
                        label = "Select years", # this DOES update
                        value = c(1985, 1987) 
# Only the first value is passed through in the update
#the inclusion of a second value does not change the slider type from one which accepts only a single value, to one which accepts a range
      )
    } else if (this_slider_type == "one"){
      message("current_slider_type is one")
      updateSliderInput(inputId = "year_select",
                          label = "Select year",
                        value = 1986 # this DOES update 
      )

    }

  })


    output$table_output <- renderTable({
      req(input$year_select)
      dta %>%
        filter(var == input$var_select) %>%
        filter(year %in% input$year_select)
    })
}

# Run the application
shinyApp(ui = ui, server = server)

推荐答案

我建议用两个单独的sliderInput包在conditionalPanel中.这个基于用户界面的解决方案比renderUI方法更快.

library(dplyr)
library(shiny)

dta <- tibble(
  var =
    c(
      rep("A", 10),
      rep("B", 3),
      rep("C", 5)
    ),
  year = c(
    1984:1993,
    1987:1989,
    1990:1994
  )
) %>%
  mutate(
    val = runif(n())
  )

ui <- fluidPage(
  
  titlePanel("Dynamic year slider"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput(
        "var_select", "Select variable",
        choices = unique(dta$var)[1],
        selected = unique(dta$var)[1]
      ),
      selectInput("slider_type", "Select slider type",
                  choices = c("One value" = "one", "Two values" = "more"),
                  selected = "one"
                  
      ),
      conditionalPanel("input.slider_type == 'one'", sliderInput("year_select_regular",
                  "Select year:",
                  min = min(subset(dta, var == unique(dta$var)[1])$year),
                  max = max(subset(dta, var == unique(dta$var)[1])$year),
                  value = min(subset(dta, var == unique(dta$var)[1])$year),
                  step = 1,
                  sep = ''
                  
      )),
      conditionalPanel("input.slider_type == 'more'", sliderInput("year_select_range",
                                                                 "Select year:",
                                                                 min = min(subset(dta, var == unique(dta$var)[1])$year),
                                                                 max = max(subset(dta, var == unique(dta$var)[1])$year),
                                                                 value = c(min(subset(dta, var == unique(dta$var)[1])$year), max(subset(dta, var == unique(dta$var)[1])$year)),
                                                                 step = 1,
                                                                 sep = ''
                                                                 
      ), style = "display:none;")
    ),
    
    mainPanel(
      tableOutput("table_output")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
  current_var <- reactive(input$var_select)
  current_slider_type <- reactive(input$slider_type)
  current_year_value  <- reactive(input$year_select)
  
  observeEvent(input$var_select, {
    message("The selected var is ", current_var())
    freezeReactiveValue(input, "year_select")
    updateSliderInput(inputId = "year_select",
                      min = min(subset(dta, var == current_var())$year),
                      max = max(subset(dta, var == current_var())$year)
                      
    )
  })
  
  observeEvent(input$slider_type, {
    this_slider_type <- current_slider_type()
    message("The current slider type is ", this_slider_type)
    if (this_slider_type == "more"){
      message("current_slider_type is more")
      
      updateSliderInput(inputId = "year_select_range",
                        label = "Select years", # this DOES update
                        value = c(1985, 1987) 
                        # Only the first value is passed through in the update
                        #the inclusion of a second value does not change the slider type from one which accepts only a single value, to one which accepts a range
      )
    } else if (this_slider_type == "one"){
      message("current_slider_type is one")
      updateSliderInput(inputId = "year_select_regular",
                        label = "Select year",
                        value = 1986 # this DOES update 
      )
      
    }
    
  })
  
  
  output$table_output <- renderTable({
    req(input$year_select)
    dta %>%
      filter(var == input$var_select) %>%
      filter(year %in% input$year_select)
  })
}

# Run the application
shinyApp(ui = ui, server = server)

R相关问答推荐

在R底座中更改白天和夜晚的背景 colored颜色

在垂直轴中包含多个ggplot2图中的平均值

根据选中三个复选框中的一个或两个来调整绘图

derrr mutate case_when grepl不能在R中正确返回值

在R中使用数据集名称

如何在ggplot中标记qqplot上的点?

将包含卷的底部25%的组拆分为2行

在连续尺度上转置标签[瀑布图,R]

R:用GGPLATE,如何在两个独立的变量中制作不同形状的散点图?

在R中,如何将误差条放置在堆叠的每个条上?

将工作目录子文件夹中的文件批量重命名为顺序

删除字符串R中的重复项

防止正则表达式覆盖以前的语句

Ggplot2如何找到存储在对象中的残差和拟合值?

在不重复主题的情况下重新排列组

conditionPanel不考虑以下条件

按两个条件自动过滤数据

R:水平旋转图

为什么R列名称忽略具有指定名称的向量,而只关注索引?

如果缺少时间,如何向日期-时间列添加时间