63

会社で保険給付プランを視覚化するための Shiny アプリを作成しています。これが私がしたいことです:

  • ユーザーが医療計画の個人の数を選択する場所がselectInputありますsliderInput
  • 一致する数の両面スライダーが表示されます (メンバーごとに 1 つ)。
  • 次に、プランの各メンバーの最良/最悪の場合の医療費の見積もりを入力できます
  • これらの見積もりを取得し、3 つのプラン オファリングの予測コストを示すプロットを並べて作成するコードを用意して、見積もりに基づいてどれが最も安価かを判断できるようにします。

ui.Rこれは、ハードコードされた入力を含む現在のファイルで、4 つのファミリをシミュレートしています。

shinyUI(pageWithSidebar(

  headerPanel("Side by side comparison"),

  sidebarPanel(

    selectInput(inputId = "class", label = "Choose plan type:",
                list("Employee only" = "emp", "Employee and spouse" = "emp_spouse",
                     "Employee and child" = "emp_child", "Employee and family" = "emp_fam")),

    sliderInput(inputId = "ind1", label = "Individual 1",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind2", label = "Individual 2",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind3", label = "Individual 3",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind4", label = "Individual 4",
                min = 0, max = 20000, value = c(0, 2500), step = 250)
    ),

  mainPanel(
    tabsetPanel(  
    tabPanel("Side by Side", plotOutput(outputId = "main_plot", width = "100%")),
    tabPanel("Summary", tableOutput(outputId = "summary"))
  )
)))

これはどのように見えるかです (透明な端のセクションは、2 つのプランからの HSA 拠出の結果です。会社の HSA 拠出の影響を示しながら、保険料と医療費の両方を示す良い方法だと思いました。したがって、単色の長さを比較するだけです)。

光沢のある例

UI入力自体が固定されているこのような例を見てきました(この場合、1つcheckboxGroupInputは存在しますが、その内容は別のUI入力からの選択に基づいて調整されます)が、数を調整する例は見たことがありません(または、たとえば、タイプ) 別の UI 入力のコンテンツの結果として生成された入力要素。

これに関する提案はありますか(可能ですか)?


私の最後の手段は、たとえば 15 個の入力スライダーを作成し、それらをゼロに初期化することです。私のコードは問題なく動作しますが、非常に大規模な家族を持つ不定期のユーザーのために、それほど多くのスライダーを作成する必要がないようにして、インターフェイスをクリーンアップしたいと考えています。


Kevin Ushay の回答に基づく更新

server.R私はルートに行こうとしましたが、これを持っています:

shinyServer(function(input, output) {

  output$sliders <- renderUI({
    members <- as.integer(input$members) # default 2
    max_pred <- as.integer(input$max_pred) # default 5000
    lapply(1:members, function(i) {
      sliderInput(inputId = paste0("ind", i), label = paste("Individual", i),
                  min = 0, max = max_pred, value = c(0, 500), step = 100)
    })

  })

})

その直後に、input各個人の費用から値を抽出しようとします。

expenses <- reactive({
    members <- as.numeric(input$members)

    mins <- sapply(1:members, function(i) {
      as.numeric(input[[paste0("ind", i)]])[1]
    })

    maxs <- sapply(1:members, function(i) {
      as.numeric(input[[paste0("ind", i)]])[2]
    })

    expenses <- as.data.frame(cbind(mins, maxs))
})

最後に、医療費の見積もりの​​高低に基づいてプロットするためのデータ フレームを格納するオブジェクトを作成する 2 つの関数があります。それらは呼び出されbest_caseworst_case両方ともオブジェクトが機能する必要があるため、この質問expensesから学んだように、最初の行として呼び出します

best_case <- reactive({

    expenses <- expenses()

    ...

)}

いくつかのエラーが発生したのでbrowser()、ビットをステップスルーして、関数内から存在しないように見えるなどのexpenses奇妙なことに気付きました。input$ind1expenses

print()また、何が起こっているのかを確認するために、その中のさまざまなステートメントをいじってみました。最も印象的なのはprint(names(input))、関数の最初の行として行う場合です。

[1] "class"    "max_pred" "members" 

[1] "class"    "ind1"     "ind2"     "max_pred" "members" 

2 つの出力が得られます。これは、定義expensesとその後の呼び出しによるものだと思います。worst_case奇妙なことに...まったく同じexpenses <- expense()線を使用すると、3 分の 1 が得られません。

print(expenses)関数内で次のようなことをexpensesすると、重複も発生します。

# the first
  mins maxs
1   NA   NA
2   NA   NA

# the second
  mins maxs
1    0  500
2    0  500

なぜとのinput要素が 2 回目に呼び出されるまで表示されず、データ フレームが正しく作成されないのかについてのヒントはありますか?ind1ind2expenses

4

3 に答える 3

21

次の構文を使用して、shiny から動的に名前が付けられた変数にアクセスできます。

input[["dynamically_named_element"]]

したがって、上記の例で、スライダー要素をそのように初期化すると

# server.R

output$sliders <- renderUI({
  members <- as.integer(input$members) # default 2
  max_pred <- as.integer(input$max_pred) # default 5000
  lapply(1:members, function(i) {
    sliderInput(inputId = paste0("ind", i), label = paste("Individual", i),
                min = 0, max = max_pred, value = c(0, 500), step = 100)
  })
})

# ui.R

selectInput("num", "select number of inputs", choices = seq(1,10,1))
uiOutput("input_ui")

次を使用して、値をテーブルに出力できます。

# server.R

output$table <- renderTable({
    num <- as.integer(input$num)

    data.frame(lapply(1:num, function(i) {
      input[[paste0("ind", i)]]
    }))
  })

# ui.R

tableOutput("table")

動作する Shiny の例については、こちらを参照してください。ここで作業の要点。

出典: Joe Cheng の最初の回答、このスレッドの約半分

于 2015-08-19T07:47:25.483 に答える