【问题标题】:Two Interdependent selectizeInput in R ShinyR Shiny中的两个相互依赖的selectizeInput
【发布时间】:2020-02-02 17:50:00
【问题描述】:

首先,我不是Shiny的专家,有很多功能我不是很了解。所以,请耐心等待我。我发现了一些其他主题(thisthis)讨论相同的问题,但我不确定如何将解决方案应用于我的问题。

我有两个selectizeInput(),一个叫Run,另一个叫Sample。我为Sample 编写的函数依赖于Run。这意味着如果我从Run 中选择一些输入,它将过滤Sample 的结果。这是下面的代码。

library(shiny)
library(tidyverse)
library(shinydashboard)

get_some_data <- structure(list(Sample = c("ADAWD", "23016", "11384"),
                                Flowcell_Line = c("1,2", "1", "1"),
                                Run = c("Run_399", "Run_399_auto2", "Run_399_auto2"),
                                Date = structure(c(1569836460, 1569836460, 1569836460),
                                                 class = c("POSIXct", "POSIXt"))), 
                           row.names = c(NA, 3L), class = "data.frame")

ui <- fluidPage(fluidRow(
    box(selectizeInput("run", "Run",
        choices = unique(get_some_data[["Run"]]),
        multiple = TRUE,
        options = list(placeholder = "Enter a Run ID...")
    )),
    box(shiny::uiOutput("ui_sample"))
))

server <- function(input, output, session)
    ({
        output$ui_sample <- renderUI(if (is.null(input$run)) {
            selectizeInput(
                inputId = 'sample',
                'Sample',
                choices = unique(get_some_data[["Sample"]]),
                multiple = TRUE,
                options = list(placeholder = 'Enter a Sample ID...')
            )
        } else {
            selectizeInput(
                inputId = 'sample',
                'Sample',
                choices = unique(filter(get_some_data, Run %in% input$run)[["Sample"]]),
                multiple = TRUE,
                options = list(placeholder = 'Enter a Sample ID...')
            )
        })
    })

shinyApp(ui = ui, server = server)

现在,我想让它可逆。我的意思是,如果我在Sample 框中输入内容,Run 框将被过滤。但我无法建立相互依赖关系,因为它创建了一个实现输入的循环。这是我尝试过的:

ui <- fluidPage(fluidRow(
    box(shiny::uiOutput("ui_run")),
    box(shiny::uiOutput("ui_sample"))
))

并添加到server:

        output$ui_run <- renderUI(
            if (is.null(input$sample)) {
                selectizeInput(
                    inputId = 'run',
                    'Run',
                    choices = unique(get_some_data[["Run"]]),
                    multiple = TRUE,
                    options = list(placeholder = 'Enter a Run ID...')
                )
            } else {
                selectizeInput(
                    inputId = 'run',
                    'Run',
                    choices = unique(filter(
                        get_some_data, Sample %in% input$sample
                    )[["Run"]]),
                    multiple = TRUE,
                    options = list(placeholder = 'Enter a Run ID...')
                )
            })

我觉得我错过了一个我不知道的重要功能......你能帮我弄清楚吗?

提前致谢。

【问题讨论】:

  • 我不认为您错过了一个重要的专用功能。这种循环依赖总是很棘手,我不知道有系统的方法来处理它们。
  • 感谢@Aurèle。好吧,我会尝试找出一些东西,如果我有任何东西会在这里发帖
  • 指针:你最好使用updateSelectizeInput 而不是renderUI。此外,在实施之前对所需行为有一个非常清晰的定义(例如:当 A 具有现有选择并且 B 更新时应该发生什么,是否应该重置所有内容,等等......)
  • @Aurèle 是的,我看到了updateSelectizeInput,虽然我不确定它到底是做什么的。我会用它做一些测试。关于所需的行为,例如,如果 A 具有现有选择并且 B 已更新(反之亦然),则不应重置任何内容。当然,除非我删除所有输入

标签: r shiny dependencies


【解决方案1】:
ui <- fluidPage(fluidRow(
  box(selectizeInput("run", "Run",
                     choices = unique(get_some_data[["Run"]]),
                     multiple = TRUE,
                     options = list(placeholder = "Enter a Run ID..."))),
  box(selectizeInput("sample", "Sample", 
                     choices = unique(get_some_data[["Sample"]]), 
                     multiple = TRUE,
                     options = list(placeholder = 'Enter a Sample ID...')))
))

server <- function(input, output, session) ({
  observeEvent(input$run, {
    updateSelectizeInput(
      session, "sample",
      choices = if (is.null(input$run)) unique(get_some_data[["Sample"]]) else
        unique(filter(get_some_data, Run %in% input$run)[["Sample"]]),
      selected = input$sample
    )
  }, ignoreNULL = FALSE)

  observeEvent(input$sample, {
    updateSelectizeInput(
      session, "run",
      choices = if (is.null(input$sample)) unique(get_some_data[["Run"]]) else
        unique(filter(get_some_data, Sample %in% input$sample)[["Run"]]),
      selected = input$run
    )
  }, ignoreNULL = FALSE)
})

shinyApp(ui = ui, server = server)

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 2023-01-23
    • 2018-11-08
    • 2017-07-15
    • 2021-08-25
    • 2011-04-26
    • 2017-05-28
    • 2023-01-07
    • 2021-09-19
    相关资源
    最近更新 更多