How to display and save User data (input) in Shiny, where the number of inputs change dynamically

346 views
Skip to first unread message

Humza Malik

unread,
Mar 31, 2015, 5:55:47 PM3/31/15
to shiny-...@googlegroups.com

I am trying to build an app in Shiny that (1) asks user for number of Assets in his/her portfolio. Depending on the numeric entry, (2) the user is presented with one numeric box to enter the % of portfolio owned AND one box for Ticker/name of the Asset. For instance, If the user enters 3 for number of assets in portfolio, he will be presented with something like this:

Asset1 ----> Enter ticker______ Enter Wight______

Asset2 ----> Enter ticker______ Enter Wight______

Asset3 ----> Enter ticker______ Enter Wight______

I have figured out the programing till this point. Now the next step that I want is for user to enter all Asset Tickers and Weights, and press submit. At this point, the user will be shown a table with each asset ticker and weight entered, along with other information such as Covariance, beta, volatility of portfolio that I will calculate my self.

The issue that I am having is how to build a data frame or rather a record of all inputs when the number of inputs can vary i.e. dynamic and depend on the number of assets user owns/enters. As such, I am completely lost. 

Below is my code. Any help will be greatly appreciated as I have been stuck on this for a while now.

SERVER.R

library(shiny)


shinyServer( function(input, output, session) {

  

  output$tickers <- renderUI({

    numAssets <- as.integer(input$assets)

    

    lapply(1:numAssets, function(i) {

      list(tags$p(tags$u(h4(paste0("Asset ", i)))),

           textInput(paste("ticker", i), label = "Ticker Name", value = "Enter ticker..."),

           numericInput(paste("weight", i), label = "Weight of Asset", value = 0))

                                    })

                             })


  # the following produced table with same number of rows as number of assets entered. However, there is no link to what the user entered for weights and ticker.

#  output$table <- renderTable ({

#    numAssets <- as.integer(input$assets)

#    df=data.frame()

#    df <-data.frame (paste0("ticker",1:numAssets), paste0("weight",1:numAssets))

#                               })

  }) 

UI.R

library(shiny)
library("shinyIncubator")


shinyUI(pageWithSidebar (

headerPanel( "Portfolio Returns"),

sidebarPanel(

numericInput("assets", label = "Enter Number of Assets in Portfolio", value="1", min="1"),
submitButton("submit"),
uiOutput("tickers")
),

mainPanel(tableOutput("table"))
))

Joe Cheng

unread,
Mar 31, 2015, 6:34:29 PM3/31/15
to Humza Malik, shiny-...@googlegroups.com
You can use bracket indexing on inputs:

tickers <- sapply(1:numAssets, function(i) {
  input[paste0("ticker", i)]
})

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/6d6faa80-2c80-4030-a0f1-183be75f9a19%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Humza Malik

unread,
Apr 1, 2015, 10:16:08 AM4/1/15
to Joe Cheng, shiny-...@googlegroups.com
Hi Joe,
Thanks a lot for the reply. I do have some follow up questions though - 
1) I am not too sure where to enter the indexing? Should I do it within the renderUI loop or outside of it? Please explain why i.e. the logic as I am new to all this.
2) What is the difference between paste0 and paste?
3)What is the difference between sapply and lapply?
Thanks again for your help on this, I do apprecaite it!
Hamza.

Humza Malik

unread,
Apr 1, 2015, 6:17:53 PM4/1/15
to Joe Cheng, shiny-...@googlegroups.com
So I have tried a bunch of different things and have googled as well but can't seem to find a fix. 
ideally, I want to print/display a table showing all entered weights and tickers. But even if i try to jsut do it for one input e.g. ticker, I seem to keep getting errors.
Here is what I have done till now :

server.R

library(shiny)

shinyServer( function(input, output, session) {
  
  output$tickers <- renderUI({
    numAssets <- as.integer(input$assets)
    
    lapply(1:numAssets, function(i) {
      list(tags$p(tags$u(h4(paste0("Asset ", i)))),
           textInput(paste("ticker", i), label = "Ticker Name", value = "Enter ticker..."),
           numericInput(paste("weight", i), label = "Weight of Asset", value = 0))
                                    })
                             })
 
  tickervalues <- reactive({
  lapply(1:numAssets, function(i) {
    input[[paste0("ticker", i)]]
  })
                  })
  output$values <- renderTable({
    tickervalues()
  })



but I get the following error:
Error in UseMethod("xtable") : 
  no applicable method for 'xtable' applied to an object of class "list"

And if i try to use dataframe to combine weight and ticker, everything falls a part.

Any suggestions guys?

Hamza.


Humza Malik

unread,
Apr 14, 2015, 4:22:20 PM4/14/15
to Joe Cheng, shiny-...@googlegroups.com
any thoughts on this? Still as lost.
Hamza.

Joe Cheng

unread,
Apr 14, 2015, 8:03:55 PM4/14/15
to Humza Malik, shiny-...@googlegroups.com
Sorry, I missed your earlier messages.

The tickervalues reactive is returning a list--maybe just using sapply instead of lapply would give you something xtable can work with (a numeric vector instead of a list). And once you've done that for tickernames as well, then you can use data.frame to combine them.
Reply all
Reply to author
Forward
0 new messages