title: R Shiny: Creating X numbers of numericInput boxes equal to number of variables
body: <p>I'm trying to create a finance-related R Shiny application. As of right now, I have a tab to create a custom portfolio, which requires me to have a <code>numericInput</code> for each variable in the original <code>source_file</code>. This is how the sample <code>source_file</code> looks like:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>Date</th>
  <th>CSI500</th>
  <th>Shanghai</th>
  <th>CSI300</th>
  <th>HSI</th>
  <th>STI</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>2016-01-01</td>
  <td>+5%</td>
  <td>-2%</td>
  <td>+5%</td>
  <td>+10%</td>
  <td>+12%</td>
  </tr>
  <tr>
  <td>2016-01-08</td>
  <td>+3%</td>
  <td>+13%</td>
  <td>-8%</td>
  <td>-3%</td>
  <td>+10%</td>
  </tr>
  <tr>
  <td>2016-01-15</td>
  <td>+2%</td>
  <td>+11%</td>
  <td>-3%</td>
  <td>+4%</td>
  <td>-15%</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>Currently, I have to manually hardcode each <code>numericInput</code> box for each variable like shown:</p>
  <pre><code>tabPanel(&quot;Custom Portfolio by Weight&quot;,
                             sidebarPanel(
                               tags$h3(&quot;Create your own Custom Portfolio by Asset Weight&quot;),
                               tags$h4(&quot;Input:&quot;),
                               numericInput(inputId = &quot;custom_csi500&quot;, &quot;CSI500 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_shanghai&quot;, &quot;Shanghai Stock Exchange (%)&quot;,  min = 0, max = 100),
                               numericInput(inputId = &quot;custom_csi300&quot;, &quot;CSI300 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_hsi&quot;, &quot;HSI (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_sti&quot;, &quot;STI (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_twse&quot;, &quot;TWSE (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_msciw&quot;, &quot;MSCI World (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_sp500&quot;, &quot;S&amp;P500 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_n225&quot;, &quot;Nikkei 225 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_lse&quot;, &quot;London Stock Exchange (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_asx&quot;, &quot;ASX (%)&quot;, min = 0, max = 100),
  </code></pre>
  <p>However, I would like to create something which could be extensible to any dataframe with different numbers of variables I specify without having to manually hard code them in. I hope anyone will be able to help me out to write a code which is able to read the number of variables in my dataframe (except the Date column) and create that many <code>numericInput</code> boxes for each variable. Thank you so much for helping out! I attached my App.R and Global.R below for reference if needed. Cheers!</p>
  <p>App.R</p>
  <pre><code># Load packages
  library(shiny)
  library(shinythemes)
  source(&quot;./global.R&quot;)
  
  # Defining UI
  ui &lt;- fluidPage(theme = shinytheme(&quot;darkly&quot;),
                  navbarPage(
                    &quot;Test App&quot;,
                    tabPanel(&quot;Custom Portfolio by Weight&quot;,
                             sidebarPanel(
                               tags$h3(&quot;Create your own Custom Portfolio by Asset Weight&quot;),
                               tags$h4(&quot;Input:&quot;),
                               numericInput(inputId = &quot;custom_csi500&quot;, &quot;CSI500 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_shanghai&quot;, &quot;Shanghai Stock Exchange (%)&quot;,  min = 0, max = 100),
                               numericInput(inputId = &quot;custom_csi300&quot;, &quot;CSI300 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_hsi&quot;, &quot;HSI (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_sti&quot;, &quot;STI (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_twse&quot;, &quot;TWSE (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_msciw&quot;, &quot;MSCI World (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_sp500&quot;, &quot;S&amp;P500 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_n225&quot;, &quot;Nikkei 225 (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_lse&quot;, &quot;London Stock Exchange (%)&quot;, min = 0, max = 100),
                               numericInput(inputId = &quot;custom_asx&quot;, &quot;ASX (%)&quot;, min = 0, max = 100),
                               mainPanel(
                               plotOutput(outputId = &quot;custom_returns&quot;),
                             ), #mainPanel
                  ), #tabpanel
                  ) #navbarPage
  ) #fluidPage
  
  server &lt;- function(input, output, session) {
  
  #to output custom_returns for Custom Portfolio by Asset Weight
      output$custom_returns &lt;- renderPlot({
        calculate_portfolio_returns(
          customrange = input$customrange,
          asset_weights = c(input$custom_csi500/100,
            input$custom_shanghai/100,                
            input$custom_csi300/100,
            input$custom_hsi/100,
            input$custom_sti/100,
            input$custom_twse/100,
            input$custom_msciw/100,
            input$custom_sp500/100,
            input$custom_n225/100,
            input$custom_lse/100,
            input$custom_asx/100,
            input$custom_custom/100))
      })
  }
    
  # Create Shiny Object
    shinyApp(ui = ui, server = server)
  
  </code></pre>
  <p>Global.R</p>
  <pre><code># Load packages
  library(tidyverse)
  library(ggcorrplot)
  library(zoo)
  library(xts)
  library(testit)
  library(PerformanceAnalytics)
  
  #choose source file to work with
  file_name = file.choose()
  source_file = read_csv(file_name)
  source_file$Date = as.Date(source_file$Date, format = &quot;%Y-%m-%d&quot;)
  
  ########################
  calculate_portfolio_returns = function(customrange, asset_weights)
  {
    #filter source file by date range specified
    source_file_filtered &lt;- source_file %&gt;% 
      filter(Date &gt;= customrange[1] &amp; Date &lt;= customrange[2])
    
    source_file_filtered_no_date &lt;- source_file_filtered[,2:length(source_file_filtered)]
    
    #create new column called Cumulative_Returns to convert % daily returns
    Cumulative_Returns &lt;- cumsum(source_file_filtered_no_date)
    
    # Extract necessary parameters
    n_cols = ncol(Cumulative_Returns)
    n_assets = n_cols
    
    #To ensure portfolio is always weighted at 100% at all times
    assert(length(asset_weights) == n_assets)
    assert(abs(sum(asset_weights)-1) &lt;= 0.001)
    
    portfolio_returns = data.matrix(Cumulative_Returns) %*% asset_weights
    portfolio_returns_with_date = cbind(source_file_filtered[,1], portfolio_returns)
    g = ggplot(data = portfolio_returns_with_date, mapping = aes(x=Date, y=portfolio_returns)) +
     geom_line(color=&quot;blue&quot;) + ggtitle(paste(&quot;Custom Portfolio Returns from&quot;, customrange[1], &quot;to&quot;, customrange[2])) +
     geom_hline(yintercept = 0, linetype = &quot;dashed&quot;) + theme(plot.title = element_text(hjust=0.5)) +
      ylab(&quot;Portfolio Returns (%)&quot;)
    print(g)
  }
  
  </code></pre>