我想在我的 Shiny 应用程序中插入一个非预定义数量的图形。我使用了一个 for 循环和一系列的 insertUI。
事情是当我运行它时,文本元素的行为符合预期,但图形都呈现相同的图像。我怎样才能防止这种情况?
这是一个reprex:
library(shiny)
ui <- fluidPage(
tags$div(
class = "this",
actionButton("go", "go")
)
)
server <- function(input, output, session) {
observeEvent( input$go , {
x <- reactiveValues(x = list(iris, mtcars, airquality))
for (i in 1:3){
insertUI(
".this",
ui = tagList(
p(paste("Number", i)),
renderPlot({
plot(x$x[[i]])
})
))
}
})
}
shinyApp(ui, server)
最佳答案
当心 for 循环中的闭包;)。 R 中没有块作用域,因此每个 for 循环迭代共享相同的迭代器变量 i
.和 renderXX
函数本质上存储不会立即计算的表达式,但只会在需要渲染时存储。
因此,当绘图准备好渲染时,for 循环已完成,i
现在是 3,每个 plot(x$x[[i]])
表达式被称为 plot(x$x[[3]])
.
您可以通过使用 local()
为每个循环迭代创建一个新范围来解决此问题。或一个函数。我最喜欢的解决方案是使用 lapply
正如您所发现的,在函数中运行每个循环迭代 i
作为函数范围的变量。
许多没有块作用域的语言都有同样的问题,比如 Python 和 JS:
关于r - Shiny - 使用 for 循环插入 UI 在每个输出中返回相同的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54327204/