Shiny 中两个相关的 selectizeInput 小部件的反应式更新

Posted

技术标签:

【中文标题】Shiny 中两个相关的 selectizeInput 小部件的反应式更新【英文标题】:Reactive updating of two related selectizeInput widgets in Shiny 【发布时间】:2018-08-28 15:17:42 【问题描述】:

我有一个数据库,将科学物种名称(即 Quercus rubra)和常用名称(即北方红橡木)联系起来。在我尝试创建的 Shiny 应用程序中,我希望有两个 selectizeInput 小部件,用户可以在其中选择从我的数据库中填充的任意数量的科学名称或常用名称。

我希望这两个输入小部件相互反应,因此如果用户从科学列表中选择多个物种,该物种的通用名称将填充通用名称输入字段,反之亦然。我对此进行了两次尝试,但在这两种情况下都没有完全正确地实现功能,因此我将不胜感激。

尝试 1:

comm <- c("northern red oak", "white pine", "balsam fir", "box elder")
sci <- c("Quercus rubra", "Pinus strobus", "Abies balsamea", "Acer negundo")
db <- as.data.frame(cbind(comm, sci))
colnames(db) <- c("common", "scientific_name")

ui <- fluidPage(

# Application title
titlePanel("Mapping Tree Distributions"),


sidebarLayout(
  sidebarPanel(
    uiOutput("scientific"),

    uiOutput("common")
  ),

  mainPanel()
 )
)


server <- function(input, output, session) 

output$scientific <- renderUI(
     common.value <- input$common.name
     default.scientific <- if (is.null(common.value)) 
       "Quercus rubra"
      else 
       as.character(db$scientific_name[db$common == common.value])
     
     selectInput("scientific.name",
                 "Scientific Name of Organism",
                 choices = db$scientific_name,
                 multiple = TRUE,
                 selectize = TRUE,
                 selected = default.scientific)
 )

output$common <- renderUI(
       scientific.value <- input$scientific.name
       default.common <- if (is.null(scientific.value)) 
            "northern red oak"
             else 
             as.character(db$common[db$scientific_name == scientific.value])
              
      selectInput("common.name",
                 "Common Name of Organism",
                 choices = db$common,
                 multiple = TRUE,
                 selectize = TRUE,
                 selected = default.common)

    )
    

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

这主要是可行的,但只要我在任一列表中选择第二个项目,它要么立即删除我之前选择的内容,要么恢复为默认选项(红橡木/Quercus rubra )。

这是我的第二次尝试:

comm <- c("northern red oak", "white pine", "balsam fir", "box elder")
sci <- c("Quercus rubra", "Pinus strobus", "Abies balsamea", "Acer negundo")
db <- as.data.frame(cbind(comm, sci))
colnames(db) <- c("common", "scientific_name")

ui <- fluidPage(

  # Application title
  titlePanel("Mapping Tree Distributions"),

  sidebarLayout(
    sidebarPanel(
      selectizeInput("scientific.name",
                  "Scientific Name of Organism",
                  choices = db$scientific_name,
                  multiple = TRUE,
                  selected = NULL),


      selectizeInput("common.name",
                  "Common Name of Organism",
                  choices = db$common,
                  multiple = TRUE,
                  selected = NULL)
    ),

    mainPanel()


  )
)


server <- function(input, output, session) 

  observeEvent(input$scientific.name, 
    updateSelectizeInput(session,
                         "common.name",
                         selected = db$common[db$scientific_name == 
                                    input$scientific.name])
  )

  observeEvent(input$common.name, 
    updateSelectizeInput(session,
                         "scientific.name",
                         selected = db$scientific_name[db$common == 
                                     input$common.name])
  )


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

第二次尝试允许我一次选择多个名称,但一旦我选择了 2 或 3 个名称,就会删除之前的选择。此外,如果我从科学列表中进行选择,它并不总是会更新常用名称列表,反之亦然。

【问题讨论】:

【参考方案1】:

在观察者内部将== 更改为%in% 可以解决问题:

  observeEvent(input$scientific.name, 
    updateSelectizeInput(session,
                             "common.name",
                             selected = db$common[db$scientific_name %in% 


input$scientific.name])
  )

  observeEvent(input$common.name, 
    updateSelectizeInput(session,
                         "scientific.name",
                         selected = db$scientific_name[db$common %in% 
                                                         input$common.name])
  )

【讨论】:

以上是关于Shiny 中两个相关的 selectizeInput 小部件的反应式更新的主要内容,如果未能解决你的问题,请参考以下文章

R Shiny:使用 Leaflet Map Click 更新多个相关下拉菜单

在 Shiny 中获取与反应式表达式相关的“错误:找不到函数”

如何防止 splitLayout、Shiny、R 中的两个输入标签重叠?

在 Shiny 中保存多个 TinyMCE 的内容

在 r shiny 中组合两个选择框值

点击Shiny App中每次迭代中的多个图