反应式、观察式、观察事件的优点

2024-04-07

我已经阅读了有关闪亮反应式编程的所有内容。我有点困惑。以下所有方法都有效,但首选方法是什么?为什么?显然,下面的示例很简单,但是在使用任何方法创建更大的应用程序时我会遇到麻烦吗?

我一直倾向于服务器代码 #1 中的风格。原因是,我能够分解 if 语句。对我来说,这似乎更具可读性。同样,下面的简单示例并不是非常复杂,但您可以轻松想象服务器代码 2 和服务器代码 3 可能会因大量嵌套的 if / if else 语句而变得非常混乱。

UI Code

library(shiny)

ui <- fluidPage(
  selectInput(inputId = 'choice',
              label = 'Choice',
              choice = c('Hello','Goodbye'),
              selected = c('Hello')
  ),

  textOutput('result')

)

服务器代码1

server <- function(input,output,session)({

  text <- reactiveValues()

  observe({
    if (input$choice == 'Hello') {
      text$result <- 'Hi there'
      }
    })

  observe({
    if (input$choice == 'Goodbye') {
      text$result <- 'See you later'
      }
    })

  output$result <- renderText({
    text$result
  })

})

shinyApp(ui = ui, server = server)

服务器代码2

server <- function(input,output,session)({

  getStatus <- reactive({

    if (input$choice == 'Hello') {
      'Hi there'
    } else if (input$choice == 'Goodbye'){
      'See you later'
    }
  })

  output$result <- renderText({
    getStatus()
  })

})

shinyApp(ui = ui, server = server)

服务器代码3

server <- function(input,output,session)({

  text <- reactiveValues()

  observeEvent(input$choice,{
    if (input$choice == 'Hello') {
      text$result <- 'Hi there'
    } else if (input$choice == 'Goodbye') {
      text$result <- 'See you later'
    }
  })

  output$result <- renderText({
    text$result
  })

})

shinyApp(ui = ui, server = server)

首先,这些东西有点模棱两可,在某些方面不是很直观,甚至在 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。当您想要一个响应式变量根据触发器而不是调用时进行计算时,请使用此选项。

请随意编辑以改进或更正这篇文章。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反应式、观察式、观察事件的优点 的相关文章

  • 如何更改 ESS 中的智能分配键(“_”到“<-”)绑定

    在 emacs ESS 中 如何正确更改 ess smart S assign 的键绑定 我尝试的是添加 custom set variables ess smart S assign key to my emacs 但这让奇怪的事情发生了
  • aggregate() 将多个输出列放入矩阵中

    我要计算某个变量的多个分位数 gt res1 lt aggregate airquality Wind list airquality Month function x quantile x c 0 9 0 95 0 975 gt head
  • 条件 RenderUI R 闪亮

    我的 renderUI 有问题 但在任何地方都找不到解决方案 可能我向谷歌问了错误的问题 不仅仅是一个闪亮的问题 而是一个基本的 R 问题 我在 R 中有一个函数 根据输入将返回一个表格或文本 所以我在我的 server R 中以这种方式创
  • ggplot 中的分层轴?

    我想知道是否可以在 GGLPOT2 或其他图形包 我只是更喜欢 ggplot 中制作分层 分段轴 我想要做的是获取下面的数据 制作一个堆积条形图 其中 x 轴上有周期 但在每个周期内 还有每种动物 那么每只动物内的条形颜色将是 颜色 变量
  • R:重新列出平面列表

    这个问题 https stackoverflow com questions 8139677有一个很好的解决方案 可以在保留列表数据类型的同时展平列表 其中unlist才不是 flatten function x unlist vector
  • 在 RGUI 中自动保存 R 源

    是否可以告诉 RGui 自动保存 R 源代码 以便它们在系统崩溃时不会丢失 我非常怀念这个功能 因为我的系统时不时地崩溃 而且我不想仅仅因为需要这个功能而使用 R Studio 或其他一些 IDE 我喜欢 RGui 提供的简单性 None
  • 如何为每个条形图制作具有定义水平边框的堆叠条形图

    我有一些数据想以一种我不知道如何在条形图中显示的方式 希望你能帮我解决这个问题 我的表由 4 列组成 簇 0 6 IgG Status mild high mild low Severe High 患者 1 16 和值 每个簇的标准化值 这
  • 如何在函数和循环中使用 data.table?

    在评估效用时data table vs dplyr 一个关键因素是在函数和循环中使用它的能力 为此 我修改了本文中使用的代码片段 data table 与 dplyr 一个可以做得很好而另一个不能做或做得很差吗 https stackove
  • 在 R/exams exams2nops() 中用零填充初始学生 ID

    当使用exams为 NOPS 考试生成 PDF 文件的软件包我想编辑学生可用的位数 reglength 我知道该软件包只允许至少 7 位数字 然而 我们学生的身份证号码只有5位数字 因此我想知道是否可以通过 PDF 操作来编辑模板 我尝试过
  • 如何使用键盘命令中断 R 中正在运行的代码?

    如何中断 R 中正在运行的脚本 假设我遇到无限循环或其他问题 并且我想停止脚本运行 有键盘命令可以做到这一点吗 如果有帮助的话 在 Python 中是 Ctrl c 我在R中尝试过 但没有成功 自我回答 几乎是其他人的评论和答案的总结 In
  • rgdax(coinbase)数据未按预期收集数据

    我正在尝试使用rgdaxR 包用于下载一些历史价格 我设置了 API 密钥等 并尝试在过去 24 小时内加载 start lt strftime Sys time Y m dT H M SZ tz UTC end lt strftime S
  • R Markdown 文档标题中的希腊字母

    R markdown 文档的标题中是否可以包含希腊字母 我试过这个 title Amylase author author date 8 March 2017 output pdf document keep tex true toc ye
  • R:从本地 tar.gz 安装 R 软件包时找不到“make”

    R 包ConvCalendar不再位于 Cran 存储库中 请参阅here https cran r project org web packages ConvCalendar index html 然而 因为我在之前的项目中大量使用了这个
  • r - 根据第一个向量重新排序第二个向量

    寻找解决方案来执行以下操作 有两个向量 a lt c 2 1 3 4 7 6 5 9 8 10 b lt c 3 2 1 6 5 4 7 8 9 10 我想创建第三个向量 它给出向量的顺序b需要重新排序 使其顺序与a 在这种情况下我想得到
  • 难以理解 R 中双括号和单括号子集之间的区别[重复]

    这个问题在这里已经有答案了 我很难理解双括号子集和单括号子集之间的区别 我在开源编程方面相当陌生 我很难理解 R 中的 help 函数 因为考虑到我目前对 R 的理解 其中的一些信息对我来说太技术性了 我尝试过谷歌搜索差异 虽然它给了我一个
  • 使用shinyjs通过javascript在闪亮的应用程序中操作现有的Leaflet地图

    我有一个闪亮的应用程序 其中包含现有的传单地图 我希望能够在渲染后使用自定义 javascript 通过shinyjs包裹 一个最小的例子如下 app R packages library dplyr library leaflet lib
  • 从 glmnet 获取变量选择顺序

    我一直在使用 glmnet R 包为一个目标变量 Y 数字 和 762 个协变量构建 LASSO 回归模型 我使用 glmnet 函数 然后coef fit s 0 056360 获取该特定 lambda 值的系数值 我现在需要的是变量选择
  • 提取模型摘要并将其存储为新列

    我是新来的purrr范例并正在努力解决它 根据一些来源 我已经设法嵌套一个数据框 在嵌套数据上运行线性模型 从每个 lm 中提取一些系数 并为每个 lm 生成摘要 我想做的最后一件事是从摘要中提取 r squared 我原以为这将是我想要实
  • 拆分并保存在新的 data.frames 中

    我有一个大 data frame 144 列 我想将其分成每组 3 列 子文件或子 data frame 然后将子 data frame 保存在单独的文件中 换句话说 file1 将包含从 1 到 3 的列 file2 将包含从 6 到 9
  • R + ggplot2 - 无法分配大小为 128.0 Mb 的向量

    我有一个 4 5MB 9 223 136 行 的文件 其中包含以下信息 0 0 0 0147938 3 67598e 07 0 0226194 7 35196e 07 0 0283794 1 10279e 06 0 033576 1 470

随机推荐