R shiny 开发web交互应用R与Shiny

如何理解shiny中的reactivity?

2019-09-14  本文已影响0人  上校的猫

官方文档

https://shiny.rstudio.com/articles/understanding-reactivity.html

理解

1. reactive 和 eventReactive

reactive 是模块化反应机制,如下代码中fib(as.numeric(input$n))被单独执行了两次,浪费资源。

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

server <- function(input, output) {
  output$nthValue    <- renderText({ fib(as.numeric(input$n)) })
  output$nthValueInv <- renderText({ 1 / fib(as.numeric(input$n)) })
}

我们使用reactive可以生成一个中间表达式,暂存结果在currentFib,后面调用currentFib省去计算过程。

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

server <- function(input, output) {
  currentFib         <- reactive({ fib(as.numeric(input$n)) })

  output$nthValue    <- renderText({ currentFib() })
  output$nthValueInv <- renderText({ 1 / currentFib() })
}

reactive会时刻监视 input 的每一个改变做出响应,但是有时候我们并不希望如此。例如运用多个条件对数据进行筛选的时候,我们可能是一个一个条件输入的,并不希望每改变一个条件就输出一个表格或者图片,这样会很浪费计算资源。这个时候希望更改完所有条件后,一起提交输入,进行计算,需要用到eventReactive

## 这个例子在拖动控件的时候,输出的表格会随着变化
library("shiny")
shinyApp(
  ui = fluidPage(
    column(4,
           sliderInput("x", "Value",
                       min = 1, max = 10,
                       value = 3),
           actionButton("button", "Show")
    ),
    column(8, tableOutput("table"))
  ),
  server = function(input, output) {
    df <-reactive({
      head(cars, input$x)
    })
    output$table <- renderTable({
      df()
    })
  }
)
## 这个滑动控件后,只有监视到按钮事件,输出才发生改变
shinyApp(
  ui = fluidPage(
    column(4,
           sliderInput("x", "Value",
                       min = 1, max = 10,
                       value = 3),
           br(),
           actionButton("button", "Show")
    ),
    column(8, tableOutput("table"))
  ),
  server = function(input, output) {
   df <- eventReactive(input$button, {
      head(cars, input$x)
    })
    output$table <- renderTable({
      df()
    })
  }
)

2. observe 和 observeEvent

observereactive 相同点都是能响应 input 的变化,不同点是 observer 没有返回值,不能向下传递,所以就不能作为 render 的输入。顾名思义,它只是起监视作用。下面例子,当滑动使 x > 5时,界面发送通知。

shinyApp(
  ui = fluidPage(
    sliderInput("x", "Value",
                min = 1, max = 10,
                value = 3)
  ),
  server = function(input, output) {
    observe({
      if(input$x > 5)
      showNotification("value > 5")
    })
  }
)

相同的 observeEvent 只是再增加一个监视条件,起延时作用。例如下面例子,滑动滑杆时,并不去判断 x > 5,只有按下按钮,才执行下面的代码。
shinyApp(
  ui = fluidPage(
    sliderInput("x", "Value",
                min = 1, max = 10,
                value = 3),
    actionButton("go", "Go")
  ),
  server = function(input, output) {
    observeEvent(input$go,{
      if(input$x > 5)
      showNotification("value > 5")
    })
  }
)
上一篇 下一篇

猜你喜欢

热点阅读