Shiny - вставка пользовательского интерфейса с циклом for возвращает одинаковые элементы в каждом выходе - PullRequest
0 голосов
/ 23 января 2019

Я хочу вставить не предопределенное количество графиков в мое приложение Shiny.Я использую для цикла и серии insertUI.

Дело в том, что когда я его запускаю, текстовые элементы ведут себя как положено, но все графики отображают одно и то же изображение.Как я могу предотвратить это?

Вот пример:

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

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Остерегайтесь замыканий в петлях;). В R нет области видимости блока, поэтому каждая итерация цикла использует одну и ту же переменную итератора i. А функции renderXX по сути хранят выражения, которые оцениваются не сразу, а только позже, когда пришло время рендеринга.

Таким образом, к тому времени, когда графики готовы к визуализации, цикл for завершен, i теперь равно 3, и каждое выражение plot(x$x[[i]]) называется plot(x$x[[3]]).

Вы можете обойти это, создавая новую область для каждой итерации цикла, используя local() или функцию. Мое любимое решение - использовать lapply, как вы обнаружили, для запуска каждой итерации цикла в функции с i в качестве переменной области действия.

Многие языки без области видимости имеют такие же особенности, как Python и JS:

0 голосов
/ 23 января 2019

Итак, нашли ответ на свой вопрос - использование lapply() делает эту работу:

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))

    lapply(1:3, function(i){
      insertUI(
        ".this", 
        ui =  tagList(
          p(paste("Number", i)),
          renderPlot({
            plot(x$x[[i]])
          })
        ))
    })
  })

}

shinyApp(ui, server)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...