title: Create dynamic number of input elements with R/Shiny
body: <p>I'm writing a Shiny app for visualizing insurance benefit plans at my company. Here is what I'd like to happen:</p>
  
  <ul>
  <li>I'll have a <code>selectInput</code> or <code>sliderInput</code> where the user will choose the number of individuals on their medical plan</li>
  <li>A matching number of double sided sliders will appear (one for each member)</li>
  <li>They can then input their estimates for best/worst case medical expenses for each member on their plan</li>
  <li>I have code that will take those estimates and create side by side plots illustrating the forecast cost on the three plan offerings so they can decide which one is least expensive based on their estimates</li>
  </ul>
  
  <p>Here's my current <code>ui.R</code> file with hard coded inputs, simulating a family of four:</p>
  
  <pre><code>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"))
    )
  )))
  </code></pre>
  
  <p>Here's what it looks like (the transparent end sections are the result of HSA contributions from two of the plans. I thought it was a nice way to show both the premiums and medical expenses while showing the impact of the company HSA contribution. Thus, you'd just compare the length of the solid colors).</p>
  
  <p><img src="https://i.stack.imgur.com/ZRhRS.png" alt="shiny-example"></p>
  
  <p>I've seen examples <a href="https://gist.github.com/wch/4211337" rel="noreferrer">like this</a> where the UI input itself is fixed (in this case, one <code>checkboxGroupInput</code> exists, but its contents are tailored based on the choice from another UI input), but I've not seen examples of tailoring <em>the number</em> (or, say, type) of input elements spawned as the result of another UI input's contents.</p>
  
  <p>Any suggestions on this (is it even possible)?</p>
  
  <hr>
  
  <p>My last resort will be to create, say, 15 input sliders and initialize them to zero. My code will work just fine, but I'd like to clean up the interface by not having to create that many sliders just for the occasional user who has a very large family.</p>
  
  <hr>
  
  <p><strong>Update based on Kevin Ushay's answer</strong></p>
  
  <p>I tried to go the <code>server.R</code> route and have this:</p>
  
  <pre><code>shinyServer(function(input, output) {
  
    output$sliders &lt;- renderUI({
      members &lt;- as.integer(input$members) # default 2
      max_pred &lt;- 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)
      })
  
    })
  
  })
  </code></pre>
  
  <p>Immediately afterwards, I try and extract the values out of <code>input</code> for each individual's expenses:</p>
  
  <pre><code>expenses &lt;- reactive({
      members &lt;- as.numeric(input$members)
  
      mins &lt;- sapply(1:members, function(i) {
        as.numeric(input[[paste0("ind", i)]])[1]
      })
  
      maxs &lt;- sapply(1:members, function(i) {
        as.numeric(input[[paste0("ind", i)]])[2]
      })
  
      expenses &lt;- as.data.frame(cbind(mins, maxs))
  })
  </code></pre>
  
  <p>Lastly, I have two functions that create objects to store a data frame for plotting based on the low and high medical expense estimates. They're called <code>best_case</code> and <code>worst_case</code> and both need the <code>expenses</code> object to work, so I call it as my first line as I learned from <a href="https://stackoverflow.com/questions/17683933/set-global-object-in-shiny">this question</a></p>
  
  <pre><code>best_case &lt;- reactive({
  
      expenses &lt;- expenses()
  
      ...
  
  )}
  </code></pre>
  
  <p>I got some errors, so I used <code>browser()</code> to step through the <code>expenses</code> bit and noticed peculiar things like <code>input$ind1</code> not seeming to exist from within the <code>expenses</code> function.</p>
  
  <p>I also played around with various <code>print()</code> statements in it to see what was happening. The most striking is when I do <code>print(names(input))</code> as the very first line in the function:</p>
  
  <pre><code>[1] "class"    "max_pred" "members" 
  
  [1] "class"    "ind1"     "ind2"     "max_pred" "members" 
  </code></pre>
  
  <p>I get <em>two</em> outputs, which I believe is due to the defining of <code>expenses</code> and subsequent calling of it. Strangely... I don't get a third when <code>worst_case</code> uses the exact same <code>expenses &lt;- expense()</code> line.</p>
  
  <p>If I do something like <code>print(expenses)</code> inside of my <code>expenses</code> function, I also get duplicates:</p>
  
  <pre><code># the first
    mins maxs
  1   NA   NA
  2   NA   NA
  
  # the second
    mins maxs
  1    0  500
  2    0  500
  </code></pre>
  
  <p>Any tips on why my <code>input</code> elements for <code>ind1</code> and <code>ind2</code> wouldn't show up until <code>expenses</code> is called the second time and thus prevent the data frame from being created correctly?</p>