我正在学习闪亮的并且正在使用与许多selectizeInputs连接的numericInput。


如果数字输入等于1或2,我想分别创建1和2 selectizeInputs,并为每个selectizeInput EDIT选择一个称为“ modalities”的向量的第i个模态:,而choices = modalities [i]仅(而不是形式)
如果数字输入等于3或4,我想分别创建3和4个selectizeInputs,它们相互连接(choices = modalities)。换句话说:如果在selectizeinputs之一中选择一个项目,我希望它从其他selectizeinputs的选择中消失。


另外(这是我遇到的麻烦)我想在每次修改numericInput时“重置”所有选定的SelectizeInput。我尝试使用下面的observeEvent,并尝试使用isolate(input $ ui_number),但是我找不到任何解决方案,因为我不知道该怎么做...!

谢谢您的帮助 !

      library(shiny)

      modalities <- LETTERS[1:10]

      ui = tabPanel("Change modalities",
                    numericInput("ui_number", label = "Number of modalities",
                                 min = 1, max = 4, value = 3),
                    uiOutput("renderui")
      )

      server = function(input, output, session) {

        # Generate modalities select lists
        output$renderui <- renderUI({
          output = tagList()
          for (i in seq_len(input$ui_number)) {
            output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                         label = paste0("Modality ", i),
                                         choices = modalities, multiple = TRUE)
          }
          return(output)
        })


        # if input$ui_number is modified to 3 or 4 : set selected to NULL ##### NOT WORKING
        observeEvent({input$ui_number},
                     {
                       n <- input$ui_number
                       if(n%in%c(3,4)){
                         for (i in seq_len(n)) {
                           updateSelectizeInput(session, paste0("ui_mod_choose",i),selected=NULL)
                         }
                       }

                     }

        )


        observe({

          n <- input$ui_number

          if(n%in%c(1,2)){ #if n=1 or 2 =>  Select the "i"th modality for each selectizeInput
            for (i in seq_len(n)) {
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = modalities[i],
                                   selected = modalities[i]
              )
            }

          } else{   # if n=3 or 4 => Remove selected modalities from other select lists
            for (i in seq_len(n)) {
              vecteur <- unlist(lapply((1:n)[-i], function(i)
                input[[paste0("ui_mod_choose",i)]]))
              updateSelectizeInput(session, paste0("ui_mod_choose",i),
                                   choices = setdiff(modalities, vecteur),
                                   selected = input[[paste0("ui_mod_choose",i)]])
            }

          }




        })

      }

      runApp(shinyApp(ui, server))


此问题对应于以下问题:

lapply function using a numericInput parameter around an observeEvent in RShiny

EDIT2:由于@Aurèle的提示,请重新尝试。
剩下的唯一问题是lapply中的1:100,这可能需要一些时间来加载(未找到在条件面板周围添加诸如1 :: input&ui_number之类的无功内容的解决方案)

      library(shiny)

      modalities <- LETTERS[1:10]

      make_conditional_selectizeInputs <- function() {
        do.call(
          div,
          lapply(1:100, function(i)
            conditionalPanel(
              condition = sprintf("%d <= input.ui_number", i),
              selectizeInput(sprintf("ui_mod_choose%d", i),
                             label = sprintf("Modality %d", i),
                             choices = character(0), multiple = TRUE, selected = NULL)
            )
          )
        )
      }



      ui <- tabPanel(
        "Change modalities",
        uiOutput("rendernumeric"),
        #numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L),
        make_conditional_selectizeInputs()
      )


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

        max <- 4

        output$rendernumeric <- renderUI({
          numericInput("ui_number", label = "Number of modalities", min = 1L, max = max, value = 1L)
        })





        n <- reactive({
          n <- input$ui_number
          if (is.null(n) || is.na(n) || !n >= 0) 0 else n
        })

        # Reset all
        observeEvent(
          eventExpr = n(),
          handlerExpr = for (i in seq_len(max))
            updateSelectizeInput(
              session, sprintf("ui_mod_choose%d", i),
              choices = if (n() %in% 1:2 && i <= n()) modalities[i] else modalities,
              selected = if (n() %in% 1:2 && i <= n()) modalities[i] else NULL
            )
        )

        all_selected <- reactive({
          unlist(lapply(seq_len(max), function(i)
            input[[sprintf("ui_mod_choose%d", i)]]))
        })

        # Update available modalities
        observeEvent(
          eventExpr = all_selected(),
          handlerExpr = if (!n() %in% 1:2) for (i in seq_len(n())) {
            x <- input[[sprintf("ui_mod_choose%d", i)]]
            other_selected <- setdiff(all_selected(), x)
            updateSelectizeInput(session, sprintf("ui_mod_choose%d", i),
                                 choices = setdiff(modalities, other_selected),
                                 selected = x)
          }
        )

      }

      runApp(shinyApp(ui, server))

最佳答案

基本上,您只需要再一行:selected = if (n %in% 1:2) modalities[i] else NULL每当您重新生成selectizeInput时。

library(shiny)

modalities <- LETTERS[1:10]

ui = tabPanel("Change modalities",
              numericInput("ui_number", label = "Number of modalities",
                           min = 1, max = 4, value = 3),
              uiOutput("renderui"))

server = function(input, output, session) {

  # Generate modalities select lists
  output$renderui <- renderUI({
    output = tagList()
    n <- input$ui_number
    n <- if (is.null(n) || is.na(n) || ! n >= 0) 0 else n
    for (i in seq_len(n)) {
      output[[i]] = selectizeInput(paste0("ui_mod_choose", i),
                                   label = paste0("Modality ", i),
                                   choices = if (n %in% 1:2) modalities[i] else modalities,
                                   multiple = TRUE,
                                   # Add this
                                   selected = if (n %in% 1:2) modalities[i] else NULL)
    }
    output
  })

  # Remove selected modalities from other select lists
  observe({
    n <- isolate(input$ui_number)
    if (!n %in% 1:2) for (i in seq_len(n)) {
      vecteur <- unlist(lapply((1:n)[-i], function(i)
        input[[paste0("ui_mod_choose",i)]]))
      updateSelectizeInput(session, paste0("ui_mod_choose",i),
                           choices = setdiff(modalities, vecteur),
                           selected = input[[paste0("ui_mod_choose",i)]])
    }
  })

}

runApp(shinyApp(ui, server))

08-19 21:59