闪亮:selectInput 基于先前的 selectInput 重置所选值

Shiny: selectInput based on previous selectInput resetting the selected value

关于这个问题有几个问题,包括 ,但我仍然不确定我需要更改什么才能正确解决这个问题。

select输入选项按预期工作,除了当我更改第二个 select 输入时,它暂时更改为所需的 selection 但随后自动返回到第一个过滤的 selection.

例如,如果为 Variable 1 选择“齿轮”,则 Variable 1 choices 会正确显示“3、4、5”以供选择可能的齿轮。如果我 select "5" 档位,它会短暂显示然后返回档位 "3" 作为选择。我不确定如何防止这种反应行为。

这是一个使用 mtcars 内置数据集的简单可重现示例:

library(tidyverse)
library(shiny)



# Variables interested in selecting
my_vars <- c("cyl", "gear", "carb")



# UI
ui <- fluidPage(
  
  # Title
  titlePanel("Reprex"),
  
  # Sidebar 
  sidebarLayout(
    sidebarPanel(
                 selectInput("sel_1",
                             "Variable 1",
                             choices  = my_vars,
                             selected = my_vars[[1]],
                             multiple = FALSE
                 ),
                 selectInput("sel_2",
                             "Variable 1 choices",
                             choices  = unique(mtcars[[ my_vars[[1]] ]]),
                             multiple = FALSE
                 )
    ), # sidebarPanel close
    
    # Plot
    mainPanel(
      plotOutput("plot_out")
    )  # mainPanel close
  )    # sidebarLayout close
)      # UI close




# Server
server <- function(input, output, session) {
  
  output$plot_out <- renderPlot({
    
    # Assign inputs
    sel_1 <- input$sel_1
    sel_2 <- input$sel_2
    
    
    # Make drop-down choice of sel_2 dependent upon user input of sel_1
    # *** Must put "shiny::observe" instead of "observe" since "observe" is masked by the Tidy infer package ***
    shiny::observe({
      updateSelectInput(session,
                        "sel_2",
                        choices = sort(unique(mtcars[[sel_1]]))
                        )
    })
    
    
    
    # Data to plot
    my_data <- mtcars %>% 
      filter(.data[[sel_1]] == sel_2)

    
    
    # Plot
    p <- ggplot(my_data, aes(x = factor(.data[[sel_1]]), y = hp)) + geom_point()
    p
    
  })
}




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

那是因为你的观察者在 renderPlot 里面。与这里无关。

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

  # Make drop-down choice of sel_2 dependent upon user input of sel_1
  observeEvent(input$sel_1, {
    updateSelectInput(session,
                      "sel_2",
                      choices = sort(unique(mtcars[[input$sel_1]]))
    )
  })
  
  output$plot_out <- renderPlot({
    
    # Assign inputs
    sel_1 <- input$sel_1
    sel_2 <- input$sel_2
    
    # Data to plot
    my_data <- mtcars %>% 
      filter(.data[[sel_1]] == sel_2)
    
    # Plot
    ggplot(my_data, aes(x = factor(.data[[sel_1]]), y = hp)) + geom_point()

  })
}

这里不需要 observeEvent 而不是 observe,因为 input$sel_1 是观察者内部唯一的反应值,但我发现 observeEvent 更具可读性.

此外,避免加载 tidyverse。这会加载大量您不需要的包。这里 dplyrggplot2 就足够了