1

I've got an issue with my current shiny code. I have to generate a dynamic number of tabs depending on the results of a given function (that part works fine). Then, I want to generate the input of these tabs in other loops of for example renderText. However, the final output of the textOutput for my generated renderText is always the one of the last renderText of the loops.

Here is a small example of the idea:

 library(shiny)
 library(shinydashboard)


 ui <- pageWithSidebar(
         headerPanel("xxx"),
         sidebarPanel(),
         mainPanel(
           uiOutput("multipleUI")
         )
      )


server <- function(input, output) {
      output$multipleUI <- renderUI({
      tabs <- list(NULL)
      for(i in 1:5){
          tabs[[i]] <- tabPanel(title = paste0("tab ",i),
                      textOutput(paste0("out",i)), # prints j as 5 in all tabs
                      paste0("local out ",i)) # prints i as current loop value for each tab)
     }
     do.call(tabBox,tabs)
  })
  observe({ 
    for(j in 1:5){ 
      txt = paste0("generated out ", j)
      print(txt) # print with current j
      output[[paste0("out",j)]] <- renderText({txt})
    }
  })
}

shinyApp(ui, server)

While it might not be that important for renderText where I can just work around the issue, I intend to render a lot of plots and tables and couldn't think of a workaround there.

I'd appreciate any help!

EDIT: I've updated the code to show a small working example

Tonio Liebrand
  • 17,189
  • 4
  • 39
  • 59
Val.M
  • 37
  • 1
  • 11

1 Answers1

2

Here's a solution that seems to work. I'm using lapply to create the tabs. Let me know if it works for what you need.

library(shiny)

ui <- pageWithSidebar(
  headerPanel("xxx"),
  sidebarPanel(),
  mainPanel(
    do.call(tabsetPanel, c(id='tab',lapply(1:5, function(i) {
      tabPanel(
        title=paste0('tab ', i), 
        textOutput(paste0('out',i))
      )
    })))
  )
)

server <- function(input, output) {     
  lapply(1:5, function(j) {
    output[[paste0('out',j)]] <- renderPrint({
      paste0('generated out ', j)
    })
  })
}

shinyApp(ui, server)
Gaurav Bansal
  • 5,221
  • 14
  • 45
  • 91
  • Yes that works perfectly! Thank you very much for your help! By any chance, do you know why these work differently? I understand that in my example the problem has something to do with the fact that R is lazy and only sets the value of j upon calling it and that at this point it has the value 5. But I don't understand how lapply works differently. – Val.M Mar 02 '17 at 09:49
  • Unfortunately, I wasn't able to figure out why your code didn't work.I used this site as a template for doing it with `lapply`: http://shiny.rstudio.com/gallery/creating-a-ui-from-a-loop.html – Gaurav Bansal Mar 02 '17 at 14:11
  • Also, would you mind officially accepting my answer if you're fine with it so we can close out this question? Thanks. – Gaurav Bansal Mar 02 '17 at 14:59
  • Done :) sorry for the delay and thanks a lot for your help – Val.M Mar 05 '17 at 21:15