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 ist

Hier 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?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage