你如何处理 Shiny Dropdown 列表中的 ID?

How do you deal with IDs in Shiny Dropdown lists?

通常在 Web 界面中,如果您有一个从显示某些文本的数据库中填充的下拉列表,并且您想在下拉列表中使用该选定文本并将其传回数据库。但是很多时候你想传递一个 ID 而不是实际显示的文本。

在下面的示例中,我有一个 global.R 文件,其中 returns 下拉菜单的数据。这模拟了从数据库返回的数据。对于每个下拉菜单,都有一个显示在下拉菜单中的文本字段和一个未显示的 "id" 字段,但我必须以某种方式访问​​下拉菜单的 "id" 字段。这是如何在 Shiny 中完成的?...因为 selectInputs 不允许您存储 ID,所以您可以像 input$DisplayName$id

一样访问它们

在下面的示例中,我只想打印 "DisplayName" selectInput 的 "id",因此如果 "Mary" 在 input$DisplayName 中,则应在RenderText 调用。

这是 运行 的代码:

require(shiny)

runApp(list(
  ui = basicPage(
    sidebarPanel(
      selectInput("Department", "Select a department", choices = as.character(GetDepartments()$Department), selected = as.character(GetDepartments()$Department[1])),
      uiOutput("DisplayName")
    ),
    mainPanel(textOutput("Text") )
  ),
  server = function(input, output, session) {


    output$DisplayName<-renderUI({
      Department <- input$Department
      print(Department)
      selectInput("DisplayName", 'DisplayName:', choices = as.character(GetDisplayName(Department)$DisplayName), selected =as.character(GetDisplayName(Department)$DisplayName[1] ))
    })


    output$Text <- renderText({

# Here I want to simulate accessing the "id" field of the input$DisplayName
#in my app I need to pass the id to a database query
#If Mary is in input$DisplayName how can I access her id of "20"?
      print("in render text") 

      return( ??? How do I access the id  = 20???) 
    })

  }
))

这是 global.r 文件,它模拟了 returns 来自数据库的代码

GetDepartments<- function(){
  df<- data.frame(Department= c("Dept A", "Dept B"), id = c(1,2))
  return(df)
}

GetDisplayName<- function(Dept){
  if(Dept == "Dept A")
  {
    df<- data.frame(DisplayName= c("Bob", "Fred"), id = c(4,6))
    return(df)
  }else
  {
    df<- data.frame(DisplayName= c("George", "Mary"), id = c(10,20))
    return(df)
  }

}

这与您的另一个问题非常相似here。正如@nrussel 所建议的,这只是一个简单的子集问题。只需调出您的部门并在名称上建立索引即可。这是一个工作示例。

编辑*** - 使数据集具有反应性以避免重复。

根据 documentation:

响应式表达式比常规 R 函数更智能。它们缓存结果并仅在它们过时时更新。第一次 运行 反应式表达式时,表达式会将其结果保存在计算机的内存中。下次你调用反应式表达式时,它可以 return 这个保存的结果而不做任何计算(这会让你的应用程序更快)。反应式表达式将使用这个新副本,直到它也变得过时。

runApp(list(
    ui = basicPage(
        sidebarPanel(
            selectInput("Department", "Select a department", 
                        choices = as.character(GetDepartments()$Department), 
                        selected = as.character(GetDepartments()$Department[1])),
            uiOutput("DisplayName")
        ),
        mainPanel(textOutput("Text") )
    ),
    server = function(input, output, session) {

        myData <- reactive({
            GetDisplayName(input$Department)
        })

        output$DisplayName<-renderUI({
            Department <- input$Department
            print(Department)
            myData <- myData()
            selectInput("DisplayName", 'DisplayName:', choices = as.character(myData$DisplayName), 
                        selected =as.character(myData$DisplayName[1] ))
        })


        output$Text <- renderText({
            print("in render text") 
            myData <- myData()
            code <- as.character(myData[myData$DisplayName == input$DisplayName,2])
            return(code)       
        })

    }
))