美文网首页数据科学与R语言 生物信息学分析
R shiny教程-6:使用响应表达式reactive()

R shiny教程-6:使用响应表达式reactive()

作者: JeremyL | 来源:发表于2020-10-04 18:24 被阅读0次
    stockVis app

    Shiny apps构建好之后,其运行与反应要快速才会吸引用户;因此,在构建Shiny apps时,耗时计算代码的放置显得尤为重要。

    #例子 - stockVis

    ##创建stockVis Shiny app

    • 创文件夹:stockVis
    • 下载: app.Rhelpers.R
    • 安装quantmod包:install.packages("quantmod")
    • 运行:runApp("stockVis")
    stockVis app

    stockVis应用程序根据股票代码查找股票价格,并将结果显示为折线图。

    • 选择要检查的股票
    • 选择一系列要回顾的日期
    • 选择是否在y轴上绘制股票价格或股票价格的对数,
    • 决定是否根据通货膨胀调整价格。

    注:注意,“为通货膨胀调整价格”复选框还不能工作。本节的任务之一是修复这个复选框。

    默认情况下,stockVis会显示SPY代码(整个标普500的一个指数)。要查找不同的股票,请键入雅虎财经能够识别的股票符号。你可以在这里查看雅虎的股票代码:here。一些常见的符号是GOOG(谷歌)、AAPL (Apple)和GS (Goldman Sachs)。

    stockVis非常依赖quantmod包中的两个功能:

    • 使用getsymbols直接从雅虎财经(Yahoo finance)和圣路易斯联邦储备银行(Federal Reserve Bank of St. Louis)等网站下载金融数据。
    • 使用chartSeries在一个吸引人的图表中显示价格。
    • stockVis还依赖于一个名为helpers.R脚本。它包含一个根据通货膨胀调整股票价格的函数。

    #复选框和日期范围

    stockVis应用程序使用了一些新的小部件:

    • 日期范围选择器,使用dateRangeInput
    • 用checkboxInput创建的几个复选框。复选框小部件非常简单。当复选框被选中时,它们返回TRUE,当复选框未被选中时返回FALSE。
    • 这些复选框在ui对象中被命名为log和adjust,这意味着您可以在服务器函数中将它们作为inputlog和inputadjust进行查找。

    #简化计算

    检查当您点击“在对数尺度上绘制y轴”时会发生什么。input$log的值会改变,这会导致renderPlot中的整个表达式重新运行:

    output$plot <- renderPlot({
      data <- getSymbols(input$symb, src = "yahoo",
                         from = input$dates[1],
                         to = input$dates[2],
                         auto.assign = FALSE)
    
      chartSeries(data, theme = chartTheme("white"),
                  type = "line", log.scale = input$log, TA = NULL)
    })
    

    当renderPlot重新运行时:

    • 它使用getSymbols从Yahoo finance重新获取数据
    • 它重新绘制图表。

    这并不好,因为您不需要重新获取数据来重新绘制绘图。事实上,如果你过于频繁地重新获取数据,雅虎财经(Yahoo finance)会切断你的服务(因为你开始看起来像个爬虫机器人)。但更重要的是,重新运行getSymbols是不必要的工作,这会降低应用程序的速度并消耗服务器。

    #响应表达式

    可以限制在使用反应表达式的反应期间重新运行的内容。
    使用reactive函数创建一个响应表达式,就像渲染render*函数。
    例如,下面是一个反应式表达式,它使用stockVis的小部件从Yahoo获取数据。

    dataInput <- reactive({
      getSymbols(input$symb, src = "yahoo",
        from = input$dates[1],
        to = input$dates[2],
        auto.assign = FALSE)
    })
    

    当您运行表达式时,它将运行getSymbols并返回结果。您可以通过调用dataInput()在renderPlot中使用价格数据。

    output$plot <- renderPlot({    
      chartSeries(dataInput(), theme = chartTheme("white"),
        type = "line", log.scale = input$log, TA = NULL)
    })
    

    响应表达式比常规R函数更聪明一些。它们缓存数据。并知道它们的值何时已经更新。

    第一次运行反应表达式时,该表达式将其结果保存在计算机的内存中。下一次调用响应表达式时,它可以返回这个保存的结果,而不进行任何计算(这会使应用程序更快)。

    反应表达式只有在知道结果是最新的情况下才会返回保存的结果。如果反应表达式获悉结果已经更新了(因为改变了小部件),表达式将重新计算结果。然后返回新的结果并保存一个新的副本。反应表达式将使用这个新的副本,直到它也更新为止。

    reactive()优势:

    • 反应式表达式在第一次运行时保存其结果。
    • 下一次调用响应表达式时,它检查保存的值是否已更新(即,它所依赖的小部件是否已更改)。
    • 值没更新,就可以调用先前保存的值,不进行任何计算;更新了的话,重新运算表达式计算结果。

    可以用reactive()来防止Shiny重新运行不必要的代码。考虑一下反应表达式将如何在下面的新stockVis应用程序中工作。

    server <- function(input, output) {
    
      dataInput <- reactive({
        getSymbols(input$symb, src = "yahoo",
                   from = input$dates[1],
                   to = input$dates[2],
                   auto.assign = FALSE)
      })
    
      output$plot <- renderPlot({
    
        chartSeries(dataInput(), theme = chartTheme("white"),
                    type = "line", log.scale = input$log, TA = NULL)
      })
    
    }
    

    当你点击“Plot y axis on the log scale”,输入input$log将改变,renderPlot将重新执行。

    • renderPlot将调用dataInput()
    • dataInput将检查dates和symb小部件是否没有更改
    • dataInput将返回其保存的股票价格数据集,而无需重新从雅虎获取数据
    • renderPlot将用选择的的轴表达方式重新绘制图表。

    #依赖性

    当在Shiny app修改了股票代码,Shiny 也会知道,并且重新画图。

    当遇到以下两种情况,Shiny会重新运行:

    • 对象的render*函数中的input中的值发生变化,
    • 对象的render*函数中的反应性表达式已经更新

    可以将反应表达式看作连接,链接input和output中的对象。output中的对象将响应链中任何下游所做的更新。(可以设计一个长链,因为反应表达式可以调用其他反应表达式)

    #修复 “Adjust prices for inflation”

    现在来修复 “Adjust prices for inflation”,用户就能够根据通货膨胀调整的价格和未调整的价格之间切换。

    server <- function(input, output) {
    
      dataInput <- reactive({
        getSymbols(input$symb, src = "yahoo",
            from = input$dates[1],
            to = input$dates[2],
            auto.assign = FALSE)
      })
    
      output$plot <- renderPlot({   
        data <- dataInput()
        if (input$adjust) data <- adjust(dataInput())
    
        chartSeries(data, theme = chartTheme("white"),
            type = "line", log.scale = input$log, TA = NULL)
      })
    }
    

    #总结

    通过使用reactive()模块化代码,可以加快应用程序的速度.

    • reactive()接受输入值或其他反应表达式的值,并返回一个新值
    • reactive()保存它们的结果,并且只会在输入发生更改时重新计算
    • 使用reactive({ })创建响应表达式
    • 调用reactive()结果,使用reactive expressions名称加括号
      • dataInput <- reactive({})的结果调用方法是dataInput();dataInput() 中有多个对象时,使用dataInput()$对象名调用
    • 只有在reactive()render* 中可以使用reactive()

    #原文:

    Use reactive expressions

    系列文章:
    R shiny教程-1:一个 Shiny app的基本组成部分
    R shiny教程-2:布局用户界面
    R shiny教程-3:添加小部件到Shiny App
    R shiny教程-4:Shiny app响应式结果展示
    R shiny教程-5:调用R程序和导入数据
    Shiny Server安装

    相关文章

      网友评论

        本文标题:R shiny教程-6:使用响应表达式reactive()

        本文链接:https://www.haomeiwen.com/subject/izbnuktx.html