0

我有一个简单的闪亮应用程序,当我启动它时会加载数据集。该应用程序有不同selectizeInput()的地方,用户可以选择一个或多个不同变量的值,他/她可以使用这些值过滤数据集。在以下可重现的示例中,我在过滤时在服务器中创建的反应性数据集通过表格显示:

library(dplyr)
library(shiny)

dataset <- data.frame("Letters" = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C"),
                      "Numbers" = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
                      "LettersNumbers" = c("G5", "G5", "G5", "G5", "G5", "G5", "F7", "F7", "F7", "F7", "F7", "F7", "E9", "E9", "E9", "E9", "E9", "E9"))

ui <- fluidPage(

br(),

  fluidRow(
    column(width = 4,
           selectizeInput(inputId = "letters",
                          label = "Letters",
                          choices = unique(dataset$Letters),
                          multiple = TRUE),

br(),
           selectizeInput(inputId = "numbers",
                          label = "Numbers",
                          choices = unique(dataset$Numbers),
                          multiple = TRUE),

br(),

           selectizeInput(inputId = "lettersnumbers",
                          label = "Letters & Numbers",
                          choices = unique(dataset$LettersNumbers),
                          multiple = TRUE)

    ),
    column(width = 4,
           tableOutput(outputId = "table")
    ),
    column(width = 4,
           textOutput(outputId = "text")
    )
  )
  
)

server <- function(input, output, session) {
  
  # Filter the initial dataset
  dataset_filtered <- reactive({

    dataset_filtered <- dataset
    
    if (!is.null(input$letters)) {
        
      dataset_filtered <- dataset_filtered %>% 
        filter(Letters %in% c(input$letters))

    }
    
    if (!is.null(input$numbers)) {
      
      dataset_filtered <- dataset_filtered %>% 
        filter(Numbers %in% c(input$numbers))
      
    }
    
    if (!is.null(input$lettersnumbers)) {
      
      dataset_filtered <- dataset_filtered %>% 
        filter(LettersNumbers %in% c(input$lettersnumbers))
      
    }
    
    return(dataset_filtered)
    
  })
  
  # Display filtered table
  output$table <- renderTable({
    
    dataset_filtered()
    
  })
  
  # Display warning message
  output$text <- renderText({
    
    if (nrow(dataset_filtered()) == 0) {
      
      print("No combinations available")
      
    }
    
  })
  
}

shinyApp(ui = ui, server = server)

问题:三个变量具有完全相同的重要性。现在让我们举一个过滤的例子:假设我选择了值AB。从表中可以看出,在Numbers列中,我只有从18的值,但没有9。现在,在第二个selectizeInput()Numbers)中,我选择9,并且该表具有预期的 0 行,并显示警告消息。但是,如果selectizeInput()我同时选择91,则会显示一些值,因为过滤器会考虑1在创建的反应向量中可用,并为此过滤。

在我看来,对这个接口进行编程的最好方法是在每次selectizeInput()做出选择时进行响应式更新。换句话说,如果我从第一个输入中选择AB ,则数字9不应该在第二个输入中可用。这对我拥有的每个输入都应该有效,没有比其他输入更重要的输入。

我尝试了几种解决方案,也使用updateSelectizeInput(),但似乎没有任何效果。你有什么建议吗?谢谢!

4

1 回答 1

0

updateSelectizeInput()和的组合observeEvent()应该满足您的要求。尝试这个:

dataset <- data.frame("Letters" = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C"),
                      "Numbers" = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
                      "LettersNumbers" = c("G5", "G5", "G5", "G5", "G5", "G5", "F7", "F7", "F7", "F7", "F7", "F7", "E9", "E9", "E9", "E9", "E9", "E9"))

ui <- fluidPage(
  
  br(),
  
  fluidRow(
    column(width = 4,
           selectizeInput(inputId = "letters",
                          label = "Letters",
                          choices = unique(dataset$Letters),
                          multiple = TRUE),
           
           br(),
           selectizeInput(inputId = "numbers",
                          label = "Numbers",
                          choices = unique(dataset$Numbers),
                          multiple = TRUE),
           
           br(),
           
           selectizeInput(inputId = "lettersnumbers",
                          label = "Letters & Numbers",
                          choices = unique(dataset$LettersNumbers),
                          multiple = TRUE)
           
    ),
    column(width = 4,
           tableOutput(outputId = "table")
    ),
    column(width = 4,
           textOutput(outputId = "text")
    )
  )
  
)

server <- function(input, output, session) {
  
  # Filter the initial dataset
  dataset_filtered <- reactive({
    
    dataset_filtered <- dataset
    
    if (is.null(input$letters) & is.null(input$numbers) & is.null(input$lettersnumbers)) {
      dataset_filtered <- dataset
      updateSelectizeInput(session, inputId="letters",choices=dataset$Letters, selected=NULL)
      updateSelectizeInput(session, inputId="numbers",choices=dataset$Numbers, selected=NULL)
      updateSelectizeInput(session, inputId="lettersnumbers",choices=dataset$LettersNumbers, selected=NULL)
    }else{
      if (!is.null(input$letters)) {
        
        dataset_filtered <- dataset_filtered %>% 
          filter(Letters %in% c(input$letters))
        
      } 
      
      if (!is.null(input$numbers)) {
        
        dataset_filtered <- dataset_filtered %>% 
          filter(Numbers %in% c(input$numbers))
        
      } 
      
      if (!is.null(input$lettersnumbers)) {
        
        dataset_filtered <- dataset_filtered %>% 
          filter(LettersNumbers %in% c(input$lettersnumbers))
        
      }
    }
    
    return(dataset_filtered)
    
  })
  
  observeEvent(input$letters, {
    updateSelectizeInput(session, inputId="lettersnumbers",choices=dataset_filtered()$LettersNumbers, selected=NULL)
    updateSelectizeInput(session, inputId="numbers",choices=dataset_filtered()$Numbers, selected=NULL)
  })
  
  observeEvent(input$numbers, {
    updateSelectizeInput(session, inputId="lettersnumbers",choices=dataset_filtered()$LettersNumbers, selected=NULL)
    updateSelectizeInput(session, inputId="letters",choices=dataset_filtered()$Letters, selected=NULL)
  })
  
  observeEvent(input$lettersnumbers, {
    updateSelectizeInput(session, inputId="letters",choices=dataset_filtered()$Letters, selected=NULL)
    updateSelectizeInput(session, inputId="numbers",choices=dataset_filtered()$Numbers, selected=NULL)
  })
  
  # Display filtered table
  output$table <- renderTable({
    
    dataset_filtered()
    
  })
  
  # Display warning message
  output$text <- renderText({
    
    if (nrow(dataset_filtered()) == 0) {
      
      print("No combinations available")
      
    }
    
  })
  
}

shinyApp(ui = ui, server = server)
于 2021-01-21T18:13:04.813 回答