How do I use `for loop` in rendering outputs

I'm just a newbie in using Shiny.

I'm trying to use for-loops to dynamically produce outputs. But, strangely, the loop doesn't work as I expected.

ui <- fluidPage(
  p("OUT1"),
  textOutput(outputId="OUT1"),
  p("OUT2"),
  textOutput(outputId="OUT2"),
  p("OUT3"),
  textOutput(outputId="OUT3")
)

server <- function(input, output, session) {
  for (i in 1:3) {
    outputId <- paste0("OUT",i)
    output[[outputId]] <- renderPrint(i)
  }
}

I expected that output slots will contain sequential numbers like 1, 2, 3, but the actual result lists all the same value (=3) for each output slot.

Result of the above code:

OUT1
[1] 3

OUT2
[1] 3

OUT3
[1] 3

I cannot understand what is happening here.

Thanks for your kind answer...

renderPrint creates a reactive version of the given function and captures its printable results into a string. In this case, all versions of the for loop share the same reference to i - so the final value of i is used in each case. To get the desired behavior, use lapply - code below.

Also see this link.

library(shiny)

ui <- fluidPage(
  p("OUT1"),
  textOutput(outputId="OUT1"),
  p("OUT2"),
  textOutput(outputId="OUT2"),
  p("OUT3"),
  textOutput(outputId="OUT3")
)

server <- function(input, output, session) {
  # observe({
  #   for (i in 1:3) {
  #     outputId <- paste0("OUT",i)
  #     output[[outputId]] <- renderPrint(i)
  #   }
  # })
  
  lapply(1:3, function(i) {
    outputId <- paste0("OUT", i)
    output[[outputId]] <- renderPrint(i)
  })
}

shinyApp(ui = ui, server = server)
2 Likes

Thank you...

I've also reached the solution before I get your reply...

What I suspected was exactly the same as what you suggest...

I've solved my problem using purrr:map but it is basically the same as your approach..

Thank you again for your kind reply...

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.