响应式变量

案例研究:使用 R 的 Shiny 构建 Web 应用

Dean Attali

Shiny Consultant

代码重复

data <- gapminder
data <- subset(
    data,
    lifeExp >= input$life[1] & lifeExp <= input$life[2]
)
if (input$continent != "All") {
    data <- subset(
        data,
        continent == input$continent
   )
}
  • 重复了 3 次
    1. renderTable()
    2. renderPlot()
    3. downloadHandler()
案例研究:使用 R 的 Shiny 构建 Web 应用

响应式变量可减少代码重复

  • 代码重复 ⇒ 需在多处维护
    • 当需要更新代码时
    • 当需要修复缺陷时
  • 容易漏改,导致缺陷
  • 用 reactive() 变量替代重复代码
案例研究:使用 R 的 Shiny 构建 Web 应用

响应式变量

output$my_table <- renderTable({
    data <- gapminder
    data <- subset(
        data,
        lifeExp >= input$life[1] & lifeExp <= input$life[2]
    )
})
my_data <- reactive({

data <- gapminder data <- subset( data, lifeExp >= input$life[1] & lifeExp <= input$life[2] )
})
output$my_table <- renderTable({ my_data() })
案例研究:使用 R 的 Shiny 构建 Web 应用

响应式变量的缓存

  • 响应式变量会缓存其值
  • 记住自己的值
  • 依赖未变时不再运行
案例研究:使用 R 的 Shiny 构建 Web 应用

响应式变量的缓存

  output$table <- renderTable({
      fit_model(input$num)
  })

  output$plot <- renderPlot({
      ggplot(
        fit_model(input$num), ...)
  })
  • fit_model() 需 5 秒
  • 调用 fit_model() 两次 = 10 秒
x <- reactive({
    fit_model(input$num)
})

output$table <- renderTable({ x() })
output$plot <- renderPlot({ ggplot(x(), ...) })
  • x() 调用两次,但 x 内部代码只运行一次
  • fit_model() 仅调用一次 = 5 秒
案例研究:使用 R 的 Shiny 构建 Web 应用

响应式变量是惰性的

  • 惰性变量 = 仅在需要值时才计算

    x <- reactive({
        fit_model(input$num)
    })
    
    output$download <- downloadHandler(
        filename = "x.csv",
        content = function(file) {
            write.csv(x(), file)
        }
    )
    
  • 只有在请求下载时才运行 x(),而不是每次 input$num 变化

案例研究:使用 R 的 Shiny 构建 Web 应用

Passons à la pratique !

案例研究:使用 R 的 Shiny 构建 Web 应用

Preparing Video For Download...