Два взаимозависимых выбора входа в R Shiny - PullRequest
1 голос
/ 04 октября 2019

Прежде всего, я не эксперт Shiny, и есть много функций, которые я не совсем понимаю. Поэтому, пожалуйста, будьте терпеливы со мной. Я нашел некоторые другие темы ( это и это ), обсуждающие ту же проблему, но я не уверен, как применить решение к моей.

Я получил два 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...')
                )
            })

Я чувствую, что есть важная функция, о которой я скучаю, о которой я не знаю. .. не могли бы вы помочь мне разобраться?

спасибо заранее.

1 Ответ

1 голос
/ 04 октября 2019
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)
...