如何避免 Shiny R plot 中的闪烁错误?
How do i avoid flashing errors in Shiny R plot?
我从 J. Cheng 那里找到了这段代码作为 freezeReactiveValue 的例子。
但是,在显示绘图之前,偶尔会暂时显示错误以代替绘图。 (需要对输入进行一些更改才能得到这个。)据我所知,问题是在很短的时间内 - X 和 Y(列)保留在以前的数据集中,并且不匹配新的数据集。例如,我在 select "pressure" 数据集后一秒钟收到错误消息 "Error in FUN: object 'speed' not found"。 (但前提是事先 "cars" 数据集被 select 编辑为 x=Speed 和 y=pressure。)显然,该图试图在它有机会更新之前获取 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)
这与反应性优先级有关,与 "invalidation of the selections" 有关。我认为确保原子更新(对数据和输入)的唯一方法是,您需要将数据更新和输入更改组合到同一个块中,否则存在依赖块被按所需顺序执行的风险(即,反应链中有多个路径)。
一种方法是对所有事情都使用副作用,而不仅仅是分配 $x
和 $y
。 (我仍然在这里寻找不需要这种副作用的解决方案......)(我借用@rawr的评论。)
使用您的 ui
,试试这个:
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()
})
}
我将 'x' 和 'y' 的赋值放到重新分配数据的同一个观察块中。有了这个,你就相对保证selectInput
在input$dataset
改变后立即更新。
我从 J. Cheng 那里找到了这段代码作为 freezeReactiveValue 的例子。 但是,在显示绘图之前,偶尔会暂时显示错误以代替绘图。 (需要对输入进行一些更改才能得到这个。)据我所知,问题是在很短的时间内 - X 和 Y(列)保留在以前的数据集中,并且不匹配新的数据集。例如,我在 select "pressure" 数据集后一秒钟收到错误消息 "Error in FUN: object 'speed' not found"。 (但前提是事先 "cars" 数据集被 select 编辑为 x=Speed 和 y=pressure。)显然,该图试图在它有机会更新之前获取 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)
这与反应性优先级有关,与 "invalidation of the selections" 有关。我认为确保原子更新(对数据和输入)的唯一方法是,您需要将数据更新和输入更改组合到同一个块中,否则存在依赖块被按所需顺序执行的风险(即,反应链中有多个路径)。
一种方法是对所有事情都使用副作用,而不仅仅是分配 $x
和 $y
。 (我仍然在这里寻找不需要这种副作用的解决方案......)(我借用@rawr的评论。)
使用您的 ui
,试试这个:
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()
})
}
我将 'x' 和 'y' 的赋值放到重新分配数据的同一个观察块中。有了这个,你就相对保证selectInput
在input$dataset
改变后立即更新。