这是问题的简单演示:
library(shiny)
ui <- fluidPage(
textOutput("Text1"),
textOutput("Text2")
)
server <- function(input, output) {
for(i in 1:2) {
id <- paste0("Text", i)
output[[id]] <- renderText(paste0("This is text #", i)) # Problem!
}
}
shinyApp(ui, server)
该程序产生输出
这是文字#2
这是文字#2
而不是#1和#2。
显然,Shiny 存储了传递给
renderText()
的表达式。在标记为 的行中# 问题! ,并在 for 循环完成后评估它们。表达式取决于变量 i
, 及其最终值 i = 2
用于评估这两个表达式。如何在仍然使用循环的同时产生正确的输出(如何强制 Shiny 在不同的表达式中使用
i
的不同值)?在我的代码中,循环限制是动态的,我不能用几个静态调用替换循环。
最佳答案
为什么 for
-loop 不起作用,请检查此示例的输出:
library(shiny)
ui <- fluidPage(
textOutput("Text1"),
textOutput("Text2")
)
server <- function(input, output) {
for(i in 1:3) {
id <- paste0("Text", i)
output[[id]] <- renderText(paste0("This is text #", i)) # Problem!
}
i=10 # we set i to 10.
}
shinyApp(ui, server)
如您所见,所有
renderText
元素使用 i 的最后一个(全局)值。 lapply
中的情况并非如此。 ,其中将参数传递给函数,但该参数未在全局环境中定义。所以你可以使用
lapply
而不是 for
-循环,像这样:library(shiny)
ui <- fluidPage(
textOutput("Text1"),
textOutput("Text2")
)
server <- function(input, output) {
lapply(1:2,function(i){
id <- paste0("Text", i)
output[[id]] <- renderText(paste0("This is text #", i)) # Problem!
})
}
shinyApp(ui, server)
输出:
如果您还希望 ui 具有响应性,可以使用
renderUI
和 uiOutput
,例如如下:library(shiny)
ui <- fluidPage(
numericInput("number_of_text","Number of text",min=1,max=10,value=3),
uiOutput('my_text')
)
server <- function(input, output) {
reactive_text <- reactive({
all_text <- lapply(1:input$number_of_text,function(i){
id <- paste0("Text", i)
renderText(paste0("This is text #", i)) # Problem!
})
# do.call(all_text,tagList)
})
output$my_text <- renderUI({
do.call(fluidRow, reactive_text())
})
}
shinyApp(ui, server)
输出:
希望这可以帮助!
关于r - 在延迟表达式评估中,R Shiny 使用变量的变化值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48135448/