反應式變數

案例研究:使用 R 的 Shiny 建置網頁應用程式

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 建置網頁應用程式

反應式變數可減少重複

  • 程式碼重複 ⇒ 需在多處維護
    • 需要更新時
    • 需要修復錯誤時
  • 容易漏改其中一處,導致錯誤
  • reactive() 變數取代重複程式碼
案例研究:使用 R 的 Shiny 建置網頁應用程式

反應式變數

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 建置網頁應用程式

反應式變數的快取機制

  • 反應式變數會「快取」其值
  • 自行記住目前的值
  • 依賴未變更時不會重跑
案例研究:使用 R 的 Shiny 建置網頁應用程式

反應式變數的快取機制

  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 建置網頁應用程式

反應式變數具有延遲求值

  • 延遲求值:直到需要時才計算

    x <- reactive({
        fit_model(input*num)
    })
    
    output$download <- downloadHandler(
        filename = "x.csv",
        content = function(file) {
            write.csv(x(), file)
        }
    )
    
  • 只有請求下載時才會執行 x(),而非每次 input$num 改變都執行

案例研究:使用 R 的 Shiny 建置網頁應用程式

一起來練習吧!

案例研究:使用 R 的 Shiny 建置網頁應用程式

Preparing Video For Download...