会社で保険給付プランを視覚化するための 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_case
、worst_case
両方ともオブジェクトが機能する必要があるため、この質問expenses
から学んだように、最初の行として呼び出します
best_case <- reactive({
expenses <- expenses()
...
)}
いくつかのエラーが発生したのでbrowser()
、ビットをステップスルーして、関数内から存在しないように見えるなどのexpenses
奇妙なことに気付きました。input$ind1
expenses
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 回目に呼び出されるまで表示されず、データ フレームが正しく作成されないのかについてのヒントはありますか?ind1
ind2
expenses