问题
As an extension of this example:
https://shiny.rstudio.com/gallery/creating-a-ui-from-a-loop.html
Say you would like the for loop to be of a length determined by a numeric input. So for example, extending the linked example (using just the second part of it):
ui <- fluidPage(
title = 'Creating a UI from a dynamic loop length',
sidebarLayout(
sidebarPanel(
# Determine Length of Loop
numericInput(inputId = "NumLoop", "Number of Loops", value = 5, min = 1, max = 5, step = 1)
),
mainPanel(
# UI output
lapply(1:input.NumLoop, function(i) {
uiOutput(paste0('b', i))
})
)
)
)
server <- function(input, output, session) {
reactive({
lapply(1:input$NumLoop, function(i) {
output[[paste0('b', i)]] <- renderUI({
strong(paste0('Hi, this is output B#', i))
})
})
})
}
shinyApp(ui = ui, server = server)
As far as I can tell there are two problems with the code:
In the UI, I don't know how to legitimately use the input from NumLoop
in the for loop of the UI output. I have experimented with the conditionalPanel
function with no luck.
In the server, once I put the loop behind a reactive
function to make use of input$NumLoop
I no longer have access to those renderUI
outputs in the UI.
Any ideas of how to solves these issues would be much appreciated.
回答1:
This should do the trick, as per @Dean, yes the second renderUI
shouldn't be there
library(shiny)
ui <- fluidPage(
title = 'Creating a UI from a dynamic loop length',
sidebarLayout(
sidebarPanel(
# Determine Length of Loop
numericInput(inputId = "NumLoop", "Number of Loops", value = 5, min = 1, max = 10, step = 1)
),
mainPanel(
# UI output
uiOutput('moreControls')
)
)
)
server <- function(input, output, session) {
output$moreControls <- renderUI({
lapply(1:input$NumLoop, function(i) {
strong(paste0('Hi, this is output B#', i),br())
})
})
}
shinyApp(ui = ui, server = server)
来源:https://stackoverflow.com/questions/52847043/how-to-create-a-ui-in-shiny-from-a-for-loop-whose-length-is-based-on-numeric-inp