我现在几次阅读有关反应式编程的Shiny文档,但我无法正确理解observeEvent
和eventReactive
之间的区别。
文档说:
每当您想要执行操作以响应事件时,请使用observeEvent。 (请注意,“重新计算值”通常不会被视为执行操作 - 请参阅eventReactive。)
...
使用eventReactive创建一个仅响应事件而更新的计算值。这就像一个普通的反应式表达式,除了它忽略了来自其反应依赖的所有常见的失效;
在我试过的所有情况下,我发现使用observeEvent
和eventReactive
之间没有区别(无论我使用哪种功能,代码都能正常工作,对性能没有明显影响)。
你能帮我弄清楚两者之间的真正区别吗?理想情况下,我想举几个例子说明它们何时可以互换,一个observeEvent
可以工作但不eventReactive
,反之亦然。
答案 0 :(得分:29)
这就像observe
和reactive
之间的区别。一个是在某个反应变量被“触发”并且意图产生副作用(observeEvent
)时运行,而另一个反应返回一个反应值并且意味着用作变量({{1} })。即使在这些函数的文档中,前者显示时没有分配给变量(因为它只是产生副作用),而后者显示为分配给变量并在以后使用。
答案 1 :(得分:23)
正如@daatali所说,这两个函数用于不同目的。
ui <- shinyUI(pageWithSidebar(
headerPanel("eventReactive and observeEvent"),
sidebarPanel(
actionButton("evReactiveButton", "eventReactive"),
br(),
actionButton("obsEventButton", "observeEvent"),
br(),
actionButton("evReactiveButton2", "eventReactive2")
),
mainPanel(
verbatimTextOutput("eText"),
verbatimTextOutput("oText")
)
))
server <- shinyServer(function(input, output) {
etext <- eventReactive(input$evReactiveButton, {
runif(1)
})
observeEvent(input$obsEventButton,{
output$oText <- renderText({ runif(1) })
})
eventReactive(input$evReactiveButton2,{
print("Will not print")
output$oText <- renderText({ runif(1) })
})
output$eText <- renderText({
etext()
})
})
shinyApp(ui=ui,server=server)
eventReactive
创建一个基于eventExpr
更改的被动值,而observeEvent
只是根据eventExpr
答案 2 :(得分:13)
我认为这里需要强调最高级别的实践方面。
eventReactive
创建一个你定义的对象
reactive
确实如此,但是你会得到通常的连锁反应行为
来自reactive
。然而,它被懒惰地评估和缓存,如
其他reactives
。
observeEvent
无法创建您定义的对象(它
创造别的东西)。它会立即进行评估,而不是缓存。
这是为了引起副作用。
因此,如果您需要数据框,矢量或图或其他内容,但想要与通常的反应链反应分离,请使用eventReactive
。
如果您只想立即产生副作用,observeEvent
就是您的票。
答案 3 :(得分:4)
提供我理解的方式,纠正我并根据需要添加更多信息。大部分信息来自https://shiny.rstudio.com/articles/action-buttons.html
要构建控制同一对象的多个操作按钮,将observeEvent()调用与reactiveValues()结合使用,这里我可以使用两个同时在同一代码中工作的actionButtons。
Code.1给出observeElement()
的效果Code.2使用eventReactive(),但如果我尝试使用两个不同的actionButtons,只有最新的一个工作,前一个按钮为null并且没有反应
代码1
library(shiny)
ui<-fluidPage(
actionButton("runif", "uniform"),
actionButton("rnorm", "Normal"),
hr(),
plotOutput("plot")
)
server<-function(input, output){
v<-reactiveValues(data=NULL)
observeEvent(
input$runif,
{
v$data<-runif(100)
}
)
observeEvent(
input$rnorm,
{
v$data<-rnorm(100)
}
)
output$plot <- renderPlot(
{
if (is.null(v$data)) return()
hist(v$data)
}
)
}
shinyApp(ui, server)
码2
library(shiny)
ui<-fluidPage(
actionButton(inputId = "norm", label = "Normal"),
actionButton(inputId = "unif", label = "Uniform"),
#Normal
plotOutput("hist")
)
server <- function(input, output) {
dnorm <- eventReactive(input$norm, {rnorm(100)})
dunif <- eventReactive(input$unif, {runif(100)})
output$hist <- renderPlot({
hist(dfnorm())
})
output$hist <- renderPlot({
hist(dunif())
})
}
shinyApp(ui, server)
答案 4 :(得分:0)
我发现this有助于理解eventReactive
:
eventReactives与反应堆类似,它们被构造为 如下:
eventReactive( event { code to run })
eventReactives不依赖于它们体内的所有反应式表达式(“ 在上面的代码段中运行)。相反,它们仅取决于 事件部分中指定的表达式。