在 R Shiny 中将 selectInput 重置为 NULL

Resetting selectInput to NULL in R Shiny

我需要能够将 R Shiny 中的几个 selectInput 小部件重置为它们的原始值 NULL(小部件中有一个空白文本区域)。到目前为止,我得到了这样的用户输入(哪个变量用作 x 轴):

  output$descrxaxis_Variable <- renderUI({
  selectInput(inputId = "descrxaxis", label = "Choose x axis variable", choices = colnames(descrDataMelted_selVars$df), multiple = TRUE)})

我正在使用这个获取该变量的列索引:

 x_ind <- reactiveValues(val = NULL)
observeEvent(input$descrxaxis, {
  x_ind$val <- which(colnames(descrDataMelted_selVars$df) == input$descrxaxis)})

我需要做的是将 x_ind 重置为 NULL,这样当用户单击“重置 X 轴”按钮时,他们之前选择的列就会消失。这是我当前执行此操作的代码:

    observeEvent(input$descrXaxisResetBtn, {
    updateSelectInput("descrxaxis", label = "Choose x axis variable", choices = colnames(descrDataMelted_selVars$df), multiple = TRUE, selected = NULL)})

但是,我也试过了:

  observeEvent(input$descrXaxisResetBtn, {
    shinyjs::useShinyjs()
    shinyjs::reset("descrxaxis")})

这些都不起作用,他们选择的先前变量仍保留在小部件文本框中。我如何让它工作?谢谢。

编辑:这是有效的代码(在回答我问题的人的帮助下)。

ui <- navbarPage(title = "SD Mesonet Quality Control", id = "navbarPage",
                     tabPanel(title = 'Metadata',
                              sidebarLayout(
                                sidebarPanel(width = 2,
                                             h4("Select Summary Variables to Plot"),
                                             div(style="display: inline-block; vertical-align:bottom; position:relative",
                                                 fluidRow(
                                                   column(10,
                                                          uiOutput("descrxaxis_Variable")),
                                                   column(2,
                                                          actionButton(inputId = "descrXaxisResetBtn", label = "Reset X", style = "padding:17px; color: #fff; background-color: #337ab7; border-color: #2e6da4"))
                                                 )
                                             ),        
                                             div(style="display: inline-block; vertical-align:bottom; position:relative",
                                                 fluidRow(
                                                   column(10,
                                                          uiOutput("descryaxis_Variable")),
                                                   column(2,
                                                          actionButton(inputId = "descrYaxisResetBtn", label = "Reset Y", style = "padding:17px; color: #fff; background-color: #337ab7; border-color: #2e6da4"))
                                                 )
                                             ),           
                                             div(style="display: inline-block; vertical-align:bottom; position:relative",
                                                 fluidRow(
                                                   column(10,
                                                          uiOutput("descrfacet_Variable")),
                                                   column(2,
                                                          actionButton(inputId = "descrFacetResetBtn", label = "Reset Facet", style = "padding:17px; color: #fff; background-color: #337ab7; border-color: #2e6da4"))
                                                 )
                                             ),        
                                             div(style="display: inline-block; vertical-align:bottom; position:relative",
                                                 fluidRow(
                                                   column(10,
                                                          uiOutput("descrcolor_Variable")),
                                                   column(2,
                                                          actionButton(inputId = "descrColorResetBtn", label = "Reset Color", style = "padding:17px; color: #fff; background-color: #337ab7; border-color: #2e6da4"))
                                                 )
                                             ),
                                             br(),
                                             actionButton("descrBtnPlot","Plot", style="color: #fff; background-color: #337ab7; border-color: #2e6da4")
                                             
                                ),
                                mainPanel(width = 10,
                                          plotlyOutput("descrSummaryStatsPlot")
                                )
                              )
                     )
    )
    
    server <- function(input,output,session){
      output$descrxaxis_Variable <- renderUI({
        selectInput(inputId = "descrxaxis", label = "Choose x axis variable", choices = colnames(descrDataMelted_selVars), multiple = TRUE, selected = character(0))})
      
      output$descryaxis_Variable <- renderUI({
        selectInput(inputId = "descryaxis", label = "Choose y axis variable", choices = colnames(descrDataMelted_selVars), multiple = TRUE)})
      
      output$descrfacet_Variable <- renderUI({
        selectInput(inputId = "descrfacet", label = "Choose facet variable", choices = colnames(descrDataMelted_selVars), multiple = TRUE)})
      
      output$descrcolor_Variable <- renderUI({
        selectInput(inputId = "descrcolor", label = "Choose color variable", choices = colnames(descrDataMelted_selVars), multiple = TRUE)})
      
      x_ind <- reactiveValues(val = NULL)
      observeEvent(input$descrxaxis, {
        x_ind$val <- which(colnames(descrDataMelted_selVars) == input$descrxaxis)})
      
      y_ind <- reactiveValues(val = NULL)
      observeEvent(input$descryaxis, {
        y_ind$val <- which(colnames(descrDataMelted_selVars) == input$descryaxis)})
      
      facet_ind <- reactiveValues(val = NULL)
      observeEvent(input$descrfacet, {
        facet_ind$val <- which(colnames(descrDataMelted_selVars) == input$descrfacet)})
      
      color_ind <- reactiveValues(val = NULL)
      observeEvent(input$descrcolor, {
        color_ind$val <- which(colnames(descrDataMelted_selVars) == input$descrcolor)})
      
      observeEvent(input$descrBtnPlot,{
        if (!is.null(x_ind$val) & !is.null(y_ind$val) & is.null(facet_ind$val) & is.null(color_ind$val)){
          p <- ggplot(descrDataMelted_selVars, aes_string(x = colnames(descrDataMelted_selVars)[x_ind$val], y = colnames(descrDataMelted_selVars)[y_ind$val])) + geom_point()}
        
        if (!is.null(x_ind$val) & !is.null(y_ind$val) & is.null(facet_ind$val) & !is.null(color_ind$val)){
          p <- ggplot(descrDataMelted_selVars, aes_string(x = colnames(descrDataMelted_selVars)[x_ind$val], y = colnames(descrDataMelted_selVars)[y_ind$val],
                                                          color = colnames(descrDataMelted_selVars)[color_ind$val])) + geom_point()}
        
        if (!is.null(x_ind$val) & !is.null(y_ind$val) & !is.null(facet_ind$val) & is.null(color_ind$val)){
          p <- ggplot(descrDataMelted_selVars, aes_string(x = colnames(descrDataMelted_selVars)[x_ind$val], y = colnames(descrDataMelted_selVars)[y_ind$val])) + geom_point() +
            facet_wrap(as.formula(paste("~",colnames(descrDataMelted_selVars)[facet_ind$val])))}
        
        if (!is.null(x_ind$val) & !is.null(y_ind$val) & !is.null(facet_ind$val) & !is.null(color_ind$val)){
          p <- ggplot(descrDataMelted_selVars, aes_string(x = colnames(descrDataMelted_selVars)[x_ind$val], y = colnames(descrDataMelted_selVars)[y_ind$val],
                                                          color = colnames(descrDataMelted_selVars)[color_ind$val])) + geom_point() +
            facet_wrap(as.formula(paste("~",colnames(descrDataMelted_selVars)[facet_ind$val])))}
        
        output$descrSummaryStatsPlot <- renderPlotly(p)
      })
      
      observeEvent(input$descrXaxisResetBtn, {
        updateSelectInput(session,"descrxaxis", selected = character(0))
      })
      
    }
    shinyApp(ui,server)

预先使用 selected=character(0)(或 selected="",正如@starja 所评论的):

    updateSelectInput("descrxaxis", label = "Choose x axis variable",
                      choices = colnames(descrDataMelted_selVars$df), multiple = TRUE, 
                      selected = character(0))

other (duplicate) question 中的一些关键组件需要修复,并且与更新输入的概念相关(但根据 this[=95= 的当前状态并不明显) ]问题):

  • 首先,不要将 observeobserveEvent 嵌套在另一个中。这可能是您的代码中的错字,但请确保所有 observe*(以及任何反应函数,就此而言)函数都有效地位于 server 函数的“top-level” .

    变化自

          observeEvent(input$descrBtnPlot,{
            ...
            output$descrSummaryStatsPlot <- renderPlotly(p)
    
    
            observeEvent(input$descrXaxisResetBtn, {
              updateSelectInput("descrxaxis", selected = character(0))
            })
          })
    

          observeEvent(input$descrBtnPlot,{
            ...
            output$descrSummaryStatsPlot <- renderPlotly(p)
          })
          observeEvent(input$descrXaxisResetBtn, {
            updateSelectInput("descrxaxis", selected = character(0))
          })
    

    (虽然不完整,请看下一点)。

  • 其次,任何update*函数的第一个参数都是session。这不是可选的。上面项目符号 1 中的代码实际上应该是

          observeEvent(input$descrBtnPlot,{
            ...
            output$descrSummaryStatsPlot <- renderPlotly(p)
          })
          observeEvent(input$descrXaxisResetBtn, {
            updateSelectInput(session, "descrxaxis", selected = character(0))
            #                 ^^^^^^^^ the only difference
          })
    

    这引出了最后一个项目符号:

  • 第三,你的server <- function(input, output)在不使用任何update*函数的情况下是可以的,但是根据上面第二点,你必须有session,这意味着您需要将服务器定义更改为

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

我将使用 ?updateSelectInput 中的示例来演示如何找到正确的答案,但在实际调用之前注入一个 browser()

library(shiny)

ui <- fluidPage(
  p("The checkbox group controls the select input"),
  checkboxGroupInput("inCheckboxGroup", "Input checkbox",
    c("Item A", "Item B", "Item C")),
  selectInput("inSelect", "Select input",
    c("Item A", "Item B", "Item C"))
)

server <- function(input, output, session) {
  observe({
    x <- input$inCheckboxGroup

    # Can use character(0) to remove all choices
    if (is.null(x))
      x <- character(0)

    browser()

    # Can also set the label and select items
    updateSelectInput(session, "inSelect",
      label = paste("Select input label", length(x)),
      choices = x,
      selected = tail(x, 1)
    )
  })
}

shinyApp(ui, server)
  1. 第一次 运行 时,它将以空选择器开始,因此我们可以 c继续退出该调试器。

  2. Select 一项。对 updateSelectInput 的调用设置 selected = tail(x, 1),因此如果我们 运行 在控制台上,我们将看到

    Browse[2]> tail(x, 1)
    [1] "Item A"
    

    c继续退出这个调试器,注意选择器现在显示 Item A.

  3. 取消选中“A”复选框,您将再次进入调试器。

    Browse[4]> tail(x, 1)
    character(0)
    

    c继续退出此调试器,您会看到选择器现在为空(取消选择)。

为什么?在内部,查看 updateSelectInput(自 1.4.0.2 起)的源代码,

updateSelectInput
# function (session, inputId, label = NULL, choices = NULL, selected = NULL) 
# {
#     choices <- if (!is.null(choices)) 
#         choicesWithNames(choices)
#     if (!is.null(selected)) 
#         selected <- as.character(selected)
#     options <- if (!is.null(choices)) 
#         selectOptions(choices, selected)
#     message <- dropNulls(list(label = label, options = options, 
#         value = selected))
#     session$sendInputMessage(inputId, message)
# }
# <bytecode: 0x00000000b8f06030>
# <environment: namespace:shiny>

看到它检查的只是!is.null(selected),所以你想使用selected=NULL既是它的默认值,又被用作“不更改所选值”的选择。


作为一个更具体的示例,我将从该应用程序的 (non-debugged) 版本开始,并添加一个“重置!”按钮将清除 selectInput:

中的选择
ui <- fluidPage(
  p("The checkbox group controls the select input"),
  checkboxGroupInput("inCheckboxGroup", "Input checkbox",
    c("Item A", "Item B", "Item C")),
  selectInput("inSelect", "Select input",
    c("Item A", "Item B", "Item C")),
  actionButton("resetsel", "Reset!")
)

server <- function(input, output, session) {
  observe({
    x <- input$inCheckboxGroup

    # Can use character(0) to remove all choices
    if (is.null(x))
      x <- character(0)

    # Can also set the label and select items
    updateSelectInput(session, "inSelect",
      label = paste("Select input label", length(x)),
      choices = x,
      selected = tail(x, 1)
    )
  })

  observeEvent(input$resetsel, {
    ### either
    updateSelectInput(session, "inSelect", selected = character(0))
    ### or
    # updateSelectInput(session, "inSelect", selected = "")
    ### both do the same thing here
  })
}

shinyApp(ui, server)

现在,shiny 演示的基本操作有效,但是当您单击重置按钮时,选择被清除。仅供参考,如果您没有对 choices= 的更改,则无需将其包含在对 updateSelectInput 的调用中。这并没有什么坏处,但只有当您认为选择列表可能需要 updated/changed 否则才有必要。