r - Shiny - 使用 for 循环插入 UI 在每个输出中返回相同的元素

标签 r shiny

我想在我的 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)


shinyui

最佳答案

当心 for 循环中的闭包;)。 R 中没有块作用域,因此每个 for 循环迭代共享相同的迭代器变量 i .和 renderXX函数本质上存储不会立即计算的表达式,但只会在需要渲染时存储。

因此,当绘图准备好渲染时,for 循环已完成,i现在是 3,每个 plot(x$x[[i]])表达式被称为 plot(x$x[[3]]) .

您可以通过使用 local() 为每个循环迭代创建一个新范围来解决此问题。或一个函数。我最喜欢的解决方案是使用 lapply正如您所发现的,在函数中运行每个循环迭代 i作为函数范围的变量。

许多没有块作用域的语言都有同样的问题,比如 Python 和 JS:

  • JavaScript closure inside loops – simple practical example
  • How do lexical closures work?
  • 关于r - Shiny - 使用 for 循环插入 UI 在每个输出中返回相同的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54327204/

    相关文章:

    r - 使用带有 $ 的逻辑向量对数据帧进行子集

    r - 如何对组中的每个元素做某事

    R 从给定的不完整日期中删除月份

    r - 垂直分布具有智能间距的多行

    r - 在 data.table 中与范围内之间

    r - 使用 if-else 从下拉列表中进行多项选择 R Shiny

    r - 如何将图像放入 R 演示幻灯片中?

    r - 在 AWS SageMaker RStudio 中部署 R 应用程序

    右对齐 Shiny dataTable 中的列

    css - 我如何找到我 Shiny 的应用程序的现有 css?