Erstellen Sie mit R / Shiny eine dynamische Anzahl von Eingabeelementen
Ich schreibe eine Shiny-App zur Visualisierung von Versicherungsplänen in meinem Unternehmen. Folgendes würde ich gerne tun:
ich nehme einselectInput
odersliderInput
wo der Benutzer die Anzahl der Personen auf ihrem medizinischen Plan wählen wirdEine übereinstimmende Anzahl von doppelseitigen Schiebereglern wird angezeigt (einer für jedes Mitglied).Sie können dann ihre Schätzungen für die besten / schlechtesten Behandlungskosten für jedes Mitglied in ihrem Plan eingebenIch habe Code, der diese Schätzungen verwendet und nebeneinander Diagramme erstellt, in denen die prognostizierten Kosten für die drei Planangebote dargestellt sind, damit sie auf der Grundlage ihrer Schätzungen entscheiden können, welches Angebot am kostengünstigsten istHier ist mein Stromui.R
Datei mit fest codierten Eingaben, die eine vierköpfige Familie simuliert:
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"))
)
)))
So sieht es aus (die transparenten Endabschnitte sind das Ergebnis von HSA-Beiträgen aus zwei der Pläne. Ich fand, es war eine gute Möglichkeit, sowohl die Prämien als auch die medizinischen Kosten anzuzeigen und gleichzeitig die Auswirkungen des HSA-Beitrags des Unternehmens darzustellen. Also, Sie würde nur die Länge der Volltonfarben vergleichen).
Ich habe Beispiele gesehenso was Wobei die Eingabe der Benutzeroberfläche selbst festgelegt ist (in diesem Fall einecheckboxGroupInput
existiert, aber sein Inhalt ist auf die Auswahl einer anderen UI-Eingabe zugeschnitten), aber ich habe keine Beispiele für das Zuschneiden gesehendie Nummer (oder sagen wir, Typ) von Eingabeelementen, die als Ergebnis des Inhalts einer anderen UI-Eingabe erzeugt wurden.
Irgendwelche Vorschläge dazu (ist das überhaupt möglich)?
Mein letzter Ausweg besteht darin, beispielsweise 15 Eingabeschieberegler zu erstellen und sie auf Null zu initialisieren. Mein Code funktioniert einwandfrei, aber ich möchte die Benutzeroberfläche aufräumen, indem ich nicht so viele Schieberegler nur für gelegentliche Benutzer mit einer sehr großen Familie erstellen muss.
Update basierend auf der Antwort von Kevin Ushay
Ich habe versucht, die zu gehenserver.R
Route und haben diese:
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)
})
})
})
Unmittelbar danach versuche ich, die Werte aus zu extrahiereninput
für die Ausgaben jedes Einzelnen:
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))
})
Schließlich habe ich zwei Funktionen, mit denen Objekte zum Speichern eines Datenrahmens zum Plotten auf der Grundlage der Schätzungen für niedrige und hohe medizinische Kosten erstellt werden. Sie heißenbest_case
undworst_case
und beide brauchen dieexpenses
Objekt zu arbeiten, so nenne ich es als meine erste Zeile, wie ich gelernt habediese Frage
best_case <- reactive({
expenses <- expenses()
...
)}
Ich habe einige Fehler bekommen, also habe ich verwendetbrowser()
Schritt durch dieexpenses
bisschen und merkwürdige Dinge wie bemerktinput$ind1
scheint nicht aus dem zu existierenexpenses
Funktion.
Ich habe auch mit verschiedenen rumgespieltprint()
Aussagen darin, um zu sehen, was geschah. Das Auffälligste ist, wenn ich es tueprint(names(input))
als allererste Zeile in der Funktion:
[1] "class" "max_pred" "members"
[1] "class" "ind1" "ind2" "max_pred" "members"
Ich bekommezwei Ausgänge, die meiner Meinung nach auf die Definition von zurückzuführen sindexpenses
und anschließender Aufruf davon. Seltsamerweise ... bekomme ich kein drittes wennworst_case
verwendet genau das gleicheexpenses <- expense()
Linie.
Wenn ich so etwas macheprint(expenses)
in meinemexpenses
Funktion bekomme ich auch Duplikate:
# the first
mins maxs
1 NA NA
2 NA NA
# the second
mins maxs
1 0 500
2 0 500
Irgendwelche Tipps, warum meineinput
Elemente fürind1
undind2
würde erst auftauchenexpenses
wird das zweite Mal aufgerufen und verhindert so, dass der Datenrahmen korrekt erstellt wird?