如何避免Shiny R图中的闪烁错误?

时间:2018-05-14 23:01:30

标签: r shiny shiny-reactivity

我发现J. Cheng的这段代码是freezeReactiveValue的一个例子。 但是,在显示绘图之前,有时会错误地显示错误以代替绘图。 (需要对输入进行一些更改才能得到这个。)据我所知,问题是在短时间内 - X和Y(列)停留在之前的数据集中,并且不匹配新数据集。例如,在选择“压力”数据集后,我收到错误消息“FUN中的错误:未找到对象'速度'”一秒钟。 (但是只有事先选择“汽车”数据集时,x =速度和y =压力。)显然,情节试图在有机会更新之前抓住x变量,但我不知道如何防止这种情况发生。发生。非常感谢你有任何提示!谢谢!

library(shiny)
library(ggplot2)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("dataset", "Dataset", c("cars", "pressure", "mtcars")),
      selectInput("x", "x variable", character(0)),
      selectInput("y", "y variable", character(0))
    ),
    mainPanel(
      plotOutput("plot")
    )
  )
)

server <- function(input, output, session) {
  dataset <- reactive({
    get(input$dataset, "package:datasets")
  })

  observe({
    freezeReactiveValue(input, "x")
    freezeReactiveValue(input, "y")
    columns <- names(dataset())
    updateSelectInput(session, "x", choices = columns, selected =    columns[[1]])
    updateSelectInput(session, "y", choices = columns, selected = columns[[2]])
  })

  output$plot <- renderPlot({
    Sys.sleep(2)
    req(input$dataset,input$x,input$y)
    ggplot(dataset(), aes_string(input$x, input$y)) + geom_point()
  })
}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:1)

这是关于反应性优先级的一点,并且与选择失效有关&#34;。我认为确保原子更新(对数据和输入)的唯一方法是,您需要将数据更新和输入更改组合到同一个块中,或者将风险依赖块组合在期望的顺序中(即,反应链中有多条路径。)

一种方法是对所有内容使用副作用,而不仅仅是分配 var blobURL = URL.createObjectURL(some_blob); var fr = document.createElement('iframe'); fr.frameBorder = 0; fr.width = 1; fr.height = 1; document.body.appendChild(fr); var doc = fr.contentDocument; var form = doc.createElement('form'); form.action = blobURL; doc.body.appendChild(form); form.submit(); setTimeout(function(){ fr.parentNode.removeChild(fr); }, 100); $x。 (我仍在寻找一种不需要这种副作用的解决方案......)(我借用@ rawr的评论。)

使用$y,试试这个:

ui

我已将作业分配给&#39; x&#39;并且&#39; y&#39;进入重新分配数据的同一个观察块。有了这个,相对保证server <- function(input, output, session) { dataset <- reactiveVal() observeEvent(input$dataset, { req(input$dataset) x <- get(input$dataset, "package:datasets") columns <- names(x) updateSelectInput(session, "x", choices = columns, selected = columns[[1L]]) updateSelectInput(session, "y", choices = columns, selected = columns[[2L]]) dataset(x) }) output$plot <- renderPlot({ req(dataset()) columns <- names(dataset()) req(all(c(input$x, input$y) %in% columns)) ggplot(dataset(), aes_string(input$x, input$y)) + geom_point() }) } 将在selectInput更改后立即更新。