0

I'm trying to come up with an app in Shiny that receives an initial inputs called "number of stakeholders", and depending on that number, I'd like it to change the amount of tabs in the navbarPage() and navlistPanel() structures.

The current code I have replicates a similar sequence as many times as the max number of fixed stakeholders I set, leaving me with a huge 10.000 lines code that repeats continuously commands as:

tabPanel("Stakeholder #3",
fluidRow(
column(2, textInput(inputId = "sh.name.3", label = "Stakeholder's name")),
column(1),
column(4, textInput(inputId = "sh.3.option.1", label = "Option #1")),
column(1),
column(4, textInput(inputId = "sh.3.option.2", label = "Option #2"))
),
fluidRow(
column(3),
column(4, textInput(inputId = "sh.3.option.3", label = "Option #3")),
column(1),
column(4, textInput(inputId = "sh.3.option.4", label = "Option #4"))
),

I'm trying to find an option that allows me to create a more compact code at the same time that provides me with a way of making a dynamic UI, which will imply the need of finding a way to be able to manage the variables dynamically as well.

Even though R naturally allows to manage variables in a very fluid way, I haven't been successful at using structures like lists, vectors or data frames in Shiny.

I checked for several days but I wasn't able to find something more elaborate than this (which has a problem with the variables resetting itself): http://shiny.rstudio.com/gallery/dynamic-ui.html

Is there any solution to perform something like what I am looking for?

Thank you in advanced.

csgillespie
  • 59,189
  • 14
  • 150
  • 185
Rafael Sierra
  • 107
  • 1
  • 2
  • 11
  • I'm assuming you know about `renderUI` and have some experience using it, and that your main problem is creating a dynamic number **of tabs**. There are plenty of examples of how to create a dynamic number of inputs, that's easy with renderUI, so I'll go ahead with the assumption that creating the tabs is the difficult part, because there aren't many examples of that. Check out [this question+answer](http://stackoverflow.com/questions/19470426/r-shiny-add-tabpanel-to-tabsetpanel-dynamicaly-with-the-use-of-renderui) on how to do that, hopefully it helps – DeanAttali Feb 08 '16 at 06:23

1 Answers1

3

Creating a dynamic set of Panels is fairly easy using lapply. Suppose your given number of stakeholders is n, your code will be:

n = 10

app <- shinyApp(
  ui = shinyUI(fluidPage(

    uiOutput("tabsets")

  )), 

  server = function(input, output, session){

    output$tabsets <- renderUI({

      Panels <- lapply(1:n, function(number){
        tabPanel(paste0("Stakeholder #", number),
            fluidRow(
             column(2, textInput(inputId = paste0("sh.name.", number), label = "Stakeholder's name")),
             column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.1"), label = "Option #1")),
             column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.2"), label = "Option #2"))
            ),
            fluidRow(
             column(4, offset = 3, textInput(inputId = paste0("sh.", number, ".option.3"), label = "Option #3")),
             column(4, offset = 1, textInput(inputId = paste0("sh.", number, ".option.4"), label = "Option #4"))
            )
         )
      })

      do.call(tabsetPanel,Panels)
    })
  }
)

runApp(app)

I also changed your empty columns to be included in the offset attribute of your non-empty columns.

K. Rohde
  • 9,439
  • 1
  • 31
  • 51
  • This is really cool. Can you demonstrate how you might access the the individual user inputs? For example, if you wanted to print a table, X_Table, that had been subset to include only rows that match the text entered in Stakeholder 1's tab; lets say your server function contains the following code: output$my_table = renderTable({small_table = X_Table[X_Table$Stakeholder1 == inputId,]; small_table}) – Slavatron Nov 04 '16 at 15:53
  • I tend to access input variables in a dynamic way via input[[]]. For example input[[c("stakeholder", n)]], where n is some number you generated. That is not really what you asked for, is it? – K. Rohde Nov 06 '16 at 09:04