Biến phản ứng

Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Dean Attali

Shiny Consultant

Trùng lặp mã

data <- gapminder
data <- subset(
    data,
    lifeExp >= input$life[1] & lifeExp <= input$life[2]
)
if (input$continent != "All") {
    data <- subset(
        data,
        continent == input$continent
   )
}
  • Bị lặp 3 lần
    1. renderTable()
    2. renderPlot()
    3. downloadHandler()
Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Biến phản ứng giảm trùng lặp mã

  • Mã trùng lặp ⇒ nhiều nơi phải bảo trì
    • Khi cần cập nhật mã
    • Khi cần sửa lỗi
  • Dễ quên một chỗ, gây lỗi
  • Dùng biến reactive() thay cho trùng lặp mã
Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Biến phản ứng

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() })
Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Bộ nhớ đệm của biến phản ứng

  • Biến phản ứng sẽ cache giá trị
  • Tự ghi nhớ giá trị của mình
  • Không chạy lại nếu phụ thuộc không đổi
Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Bộ nhớ đệm của biến phản ứng

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

  output$plot <- renderPlot({
      ggplot(
        fit_model(input$num), ...)
  })
  • fit_model() mất 5s
  • Gọi fit_model() hai lần = 10s
x <- reactive({
    fit_model(input$num)
})

output$table <- renderTable({ x() })
output$plot <- renderPlot({ ggplot(x(), ...) })
  • Gọi x() hai lần, mã trong x chỉ chạy một lần
  • fit_model() gọi một lần = 5s
Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Biến phản ứng là lười

  • Biến lười = chỉ tính khi cần giá trị

    x <- reactive({
        fit_model(input$num)
    })
    
    output$download <- downloadHandler(
        filename = "x.csv",
        content = function(file) {
            write.csv(x(), file)
        }
    )
    
  • x() chỉ chạy khi tải xuống được yêu cầu, không phải mỗi lần input$num đổi

Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Passons à la pratique !

Nghiên cứu tình huống: Xây dựng ứng dụng web với Shiny trong R

Preparing Video For Download...