Crea un número dinámico de elementos de entrada con R / Shiny

Estoy escribiendo una aplicación Shiny para visualizar los planes de beneficios de seguro en mi empresa. Esto es lo que me gustaría que sucediera:

tendré unselectInput osliderInput donde el usuario elegirá el número de personas en su plan médicoAparecerá un número coincidente de controles deslizantes de doble cara (uno para cada miembro)Luego pueden ingresar sus estimaciones para los gastos médicos de mejor / peor caso para cada miembro en su planTengo un código que tomará esas estimaciones y creará gráficos paralelos que ilustran el costo de pronóstico en las tres ofertas del plan para que puedan decidir cuál es la menos costosa según sus estimaciones.

Aquí está mi actualui.R Archivo con entradas codificadas, simulando una familia de cuatro:

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"))
  )
)))

Esto es lo que parece (las secciones finales transparentes son el resultado de las contribuciones de HSA de dos de los planes. Pensé que era una buena forma de mostrar tanto las primas como los gastos médicos al tiempo que mostraba el impacto de la contribución de HSA de la compañía. acabo de comparar la longitud de los colores sólidos).

He visto ejemplosMe gusta esto donde la entrada de la interfaz de usuario en sí es fija (en este caso, unacheckboxGroupInput existe, pero su contenido se adapta en función de la elección de otra entrada de la interfaz de usuario), pero no he visto ejemplos de adaptaciónel número (o, digamos, tipo) de elementos de entrada generados como resultado de los contenidos de otra entrada de UI.

¿Alguna sugerencia sobre esto (es incluso posible)?

Mi último recurso será crear, digamos, 15 controles deslizantes de entrada e inicializarlos a cero. Mi código funcionará bien, pero me gustaría limpiar la interfaz al no tener que crear tantos controles deslizantes solo para el usuario ocasional que tiene una familia muy grande.

Actualización basada en la respuesta de Kevin Ushay.

Traté de ir alserver.R Ruta y tener esto:

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)
    })

  })

})

Inmediatamente después, intento extraer los valores deinput para los gastos de cada individuo:

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))
})

Por último, tengo dos funciones que crean objetos para almacenar un marco de datos para trazar en función de las estimaciones de gastos médicos bajas y altas. Ellos se llamanbest_case yworst_case y ambos necesitan elexpenses objeto para trabajar, así que lo llamo mi primera línea como aprendí deesta pregunta

best_case <- reactive({

    expenses <- expenses()

    ...

)}

Tengo algunos errores, así que utilicébrowser() para pasar a través de laexpenses Poco y notó cosas peculiares comoinput$ind1 no parece existir desde dentro de laexpenses función.

También jugué con variosprint() Declaraciones en él para ver qué estaba pasando. Lo más llamativo es cuando lo hago.print(names(input)) como la primera línea en la función:

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

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

yo obtengodos salidas, que creo que se debe a la definición deexpenses y posterior convocatoria de la misma. Extrañamente ... no consigo un tercero cuandoworst_case usa exactamente lo mismoexpenses <- expense() línea.

Si hago algo comoprint(expenses) dentro de miexpenses Función, también obtengo duplicados:

# the first
  mins maxs
1   NA   NA
2   NA   NA

# the second
  mins maxs
1    0  500
2    0  500

Cualquier consejo sobre por qué miinput elementos paraind1 yind2 no aparecería hastaexpenses ¿Se llama la segunda vez y, por lo tanto, impide que el marco de datos se cree correctamente?

Respuestas a la pregunta(3)

Su respuesta a la pregunta