ShinyでselectInputの選択肢を制御データから動的に生成する

Shinyでプルダウンメニューを表示するためにはselectInputを使います。
このときの選択肢はオプションchoicesで設定します。

#ui.R
shinyUI(fluidPage(
  titlePanel("select input"),
  sidebarLayout(
    sidebarPanel(
      selectInput("select", label = "select input", choices = list("Choice 1", "Choice 2"))
    ),
    mainPanel()
  )
))

通常はこのようにui.Rの中で設定しますが、server.Rで持っている制御変数から選択肢を生成したいこともあるでしょう。

二つ選択肢があります。
一つは下記のようにserver.RでselectInputrenderUIとしてui.Rで定義したhtmlOutputで受けるようにする方法。

#ui.R
shinyUI(fluidPange(
  titlePanel("select input(dynamic) 1"),
  sidebarLayout(
    sidebarPanel(
      htmlOutput("html.select")
    ),
    mainPanel()
  )
)
#server.R
shinyServer(function(input, output){
  myoption <- c("Choice 1", "Choice 2")
  output$html.select <- renderUI({
    selectInput("select", label = "select input", choices = myoption)
  })
})

この方法は柔軟で、selectInputに限らずあらゆるUIに適用できます。
ただ欠点はui.Rの読み込み時点ではフォームが無いため描画が遅いという点です。
よって私は次のselectInputUpdateを使って自動更新する方法が好みです。

#ui.R
shinyUI(fluidPange(
  titlePanel("select input(dynamic) 2"),
  sidebarLayout(
    sidebarPanel(
      selectInput("select", label = "select input", choices = "")
    ),
    mainPanel()
  )
)
#server.R
shinyServer(function(input, output, session){ 
  myoption <- c("Choice 1", "Choice 2")
  observe({
    updateSelectInput(session, "select", choices = myoption)
  })
})

updateSelectInputobserve({...})で囲います。
またupdateSelectInputsessionを渡す必要があるため、shinyServerに渡す無名関数の変数にもsessionを追加しておきます。

欠点はupdateSelectInputはオプションlabel, choices, selectedだけしか制御できない点です。
よってたとえばstyleを制御したい場合には1つめの選択を取る必要があります。

参考

コメントを残す