首先,这些东西有点模棱两可,在某些方面不是很直观,甚至在 Shiny 博客上也是这么说的!
这是我对这个话题的最好理解。
让我们从reactive
反应函数允许用户监视输入或其他变化变量的状态,并返回要在代码中其他地方使用的值。对反应变量的监控被认为是惰性的,“反应式表达式使用惰性求值;也就是说,当它们的依赖项发生变化时,它们不会立即重新执行,而是等到其他人调用它们为止。(Source) https://shiny.rstudio.com/reference/shiny/1.1.0/reactive.html".您在示例 2 中很好地展示了这一点,因为您可以在renderText
环境中,一旦调用反应式调用内的代码,就会执行并重新评估变量。
对于科学迷来说,这很像量子力学,通过调用反应变量(观察它)导致它通过重新评估而改变,太牵强了?
Now to observe
Observe 与响应式类似,主要区别在于它不会向除自身之外的任何其他环境返回任何值,并且它不是惰性的。观察功能持续监控其环境中所有无功值的任何变化并在这些值更改时在其环境中运行代码。因此,observe 不是一个“惰性”评估,因为它在重新评估之前不会等待被调用。再次注意,您不能从观察中分配变量。
为了实验目的:
server <- function(input,output,session)({
observe({
if (input$choice == 'Hello') {
getStatus <- 'Hi there'
}
})
observe({
if (input$choice == 'Goodbye') {
getStatus <- 'See you later'
}
})
output$result <- renderText({
getStatus
})
})
shinyApp(ui = ui, server = server)
需要注意的是,在执行代码期间observe
,我们可以操纵外部环境反应变量。在你的情况下你分配text <- reactiveValues()
然后通过调用来操纵它text$result <- 'Hi there'
。我们还可以做一些事情,比如更新selectInput
选择,或其他闪亮的小部件,但我们不能在这个环境中分配任何非反应性变量,就像上面示例中的 getStatus 一样。这个想法在observe
文档,
“观察者就像一个反应式表达式,它可以读取反应式值并调用反应式表达式,并且当这些依赖关系发生变化时会自动重新执行。但与反应式表达式不同的是,它不会产生结果,也不能用作其他反应式表达式的输入。因此,观察者仅对其副作用有用(例如,执行 I/O)(Source https://shiny.rstudio.com/reference/shiny/0.14/observe.html)"
Lastly, observeEvent
最好的使用方法observeEvent
是将其视为定义的触发器,因为它监视一个事件或变量的变化,然后在事件发生时触发。我最常使用它来观察按钮的输入,因为这是一个定义的事件,我希望在按下按钮后发生一些事情。它使用一个isolate
我认为这是这个函数如何工作的完美名称。
在这个环境中,我们可以调用一堆反应变量,但我们只定义一个作为触发器。之间的主要区别observeEvent
and observe
是触发器,如observe
任何变化都会运行,并且observeEvent
等待触发。请注意,此环境与观察环境类似,因为它不返回非反应变量。
Summary
这是一个将所有这些想法结合在一起的示例:
library(shiny)
ui<-
fluidPage(
fluidRow(
column(4,
h2("Reactive Test"),
textInput("Test_R","Test_R"),
textInput("Test_R2","Test_R2"),
textInput("Test_R3","Test_R3"),
tableOutput("React_Out")
),
column(4,
h2("Observe Test"),
textInput("Test","Test"),
textInput("Test2","Test2"),
textInput("Test3","Test3"),
tableOutput("Observe_Out")
),
column(4,
h2("Observe Event Test"),
textInput("Test_OE","Test_OE"),
textInput("Test_OE2","Test_OE2"),
textInput("Test_OE3","Test_OE3"),
tableOutput("Observe_Out_E"),
actionButton("Go","Test")
)
),
fluidRow(
column(8,
h4("Note that observe and reactive work very much the same on the surface,
it is when we get into the server where we see the differences, and how those
can be exploited for diffrent uses.")
))
)
server<-function(input,output,session){
# Create a reactive Evironment. Note that we can call the varaible outside same place
# where it was created by calling Reactive_Var(). When the varaible is called by
# renderTable is when it is evaluated. No real diffrence on the surface, all in the server.
Reactive_Var<-reactive({c(input$Test_R, input$Test_R2, input$Test_R3)})
output$React_Out<-renderTable({
Reactive_Var()
})
# Create an observe Evironment. Note that we cannot access the created "df" outside
# of the env. A, B,and C will update with any input into any of the three Text Feilds.
observe({
A<-input$Test
B<-input$Test2
C<-input$Test3
df<-c(A,B,C)
output$Observe_Out<-renderTable({df})
})
#We can change any input as much as we want, but the code wont run until the trigger
# input$Go is pressed.
observeEvent(input$Go, {
A<-input$Test_OE
B<-input$Test_OE2
C<-input$Test_OE3
df<-c(A,B,C)
output$Observe_Out_E<-renderTable({df})
})
}
shinyApp(ui, server)
reactive
创建一个变量可以通过用户输入随时间改变,仅在调用时评估“惰性”含义。
observe
持续监控反应事件和变量,无论何时ANY反应变量在环境(观察到的环境)中发生变化,代码被评估。可以更改先前定义的反应变量的值,不能创建/返回变量。
observeEvent
(多米诺骨牌效应)
持续监控ONE定义反应变量/事件(触发器),并在触发器的更改/输入激活触发器时运行代码。可以更改先前定义的反应变量的值,不能创建/返回变量。
eventReactive
创建一个变量,具有类似于定义的触发器observeEvent
。当您想要一个响应式变量根据触发器而不是调用时进行计算时,请使用此选项。
请随意编辑以改进或更正这篇文章。