我对isolate()和observeEvent()的用法感到困惑。如下所示的代码,这两个代码似乎执行相同的工作 - 仅在单击按钮后渲染绘图。 但是,当我在部署在shinyapps.io 上的应用程序中使用isolate() 函数时,我的应用程序由于内存使用量过多而崩溃。 (我在这里简化了图形代码只是为了演示。实际的代码要复杂得多。)我想知道isolate()是否对这个错误做了任何事情。用observeEvent()替换isolate()函数是否有助于提高性能?
library(shiny)
library(stats)
runApp(list(
ui = bootstrapPage(
textInput(inputId = "text_in",
label = "Type something:"),
actionButton(inputId = "submit",
label = "submit"),
plotOutput(outputId = "testpic")
),
server = function(input, output) {
output$testpic <- renderPlot({
if (input$submit == FALSE) return()
isolate({
x <- as.matrix(mtcars)
rc <- rainbow(nrow(x), start = 0, end = .3)
cc <- rainbow(ncol(x), start = 0, end = .3)
heatmap(x, col = cm.colors(256), scale = "column",
RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
xlab = input$text_in, ylab = input$text_in,
main = input$text_in)
})
})
}
))
library(shiny)
library(stats)
runApp(list(
ui = bootstrapPage(
textInput(inputId = "text_in",
label = "Type something:"),
actionButton(inputId = "submit",
label = "submit"),
plotOutput(outputId = "testpic")
),
server = function(input, output) {
vplot <- eventReactive(input$submit, {
x <- as.matrix(mtcars)
rc <- rainbow(nrow(x), start = 0, end = .3)
cc <- rainbow(ncol(x), start = 0, end = .3)
heatmap(x, col = cm.colors(256), scale = "column",
RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
xlab = input$text_in, ylab = input$text_in,
main = input$text_in)
})
observeEvent(input$submit, {
output$testpic <- renderPlot({vplot()})
})
}
))
我使用profvis()来比较它们的性能差异。事实证明,也许isolate()比observeEvent做得更好,这相当令人震惊,并且违背了我之前的知识。
将
output
槽封闭在观察者内部是不好的做法。我认为这就是为什么 profvis
报告表现最差。
我看到服务器的三种可能性:
library(shiny)
ui <- bootstrapPage(
textInput(inputId = "text_in", label = "Type something:"),
actionButton(inputId = "submit", label = "submit"),
plotOutput(outputId = "testpic")
)
server1 <- function(input, output) {
output$testpic <- renderPlot({
req(input$submit)
isolate({
x <- as.matrix(mtcars)
rc <- rainbow(nrow(x), start = 0, end = .3)
cc <- rainbow(ncol(x), start = 0, end = .3)
heatmap(x, col = cm.colors(256), scale = "column",
RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
xlab = input$text_in, ylab = input$text_in,
main = input$text_in)
})
})
}
server2 <- function(input, output) {
Heatmap <- eventReactive(input$submit, {
x <- as.matrix(mtcars)
rc <- rainbow(nrow(x), start = 0, end = .3)
cc <- rainbow(ncol(x), start = 0, end = .3)
heatmap(x, col = cm.colors(256), scale = "column",
RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
xlab = input$text_in, ylab = input$text_in,
main = input$text_in)
})
output$testpic <- renderPlot({
Heatmap()
})
}
server3 <- function(input, output) {
output$testpic <- renderPlot({
x <- as.matrix(mtcars)
rc <- rainbow(nrow(x), start = 0, end = .3)
cc <- rainbow(ncol(x), start = 0, end = .3)
heatmap(x, col = cm.colors(256), scale = "column",
RowSideColors = rc, ColSideColors = cc, margins = c(5,10),
xlab = input$text_in, ylab = input$text_in,
main = input$text_in)
}) |> bindEvent(input$submit)
}
然后你可以运行:
profvis::profvis({
app <- shinyApp(ui, server1)
runApp(app)
})
profvis::profvis({
app <- shinyApp(ui, server2)
runApp(app)
})
profvis::profvis({
app <- shinyApp(ui, server3)
runApp(app)
})
我尝试过,结论是
server3
在记忆方面是最好的,而server1
,使用isolate
,是最差的。