参见:https://shiny.rstudio.com/tutorial/written-tutorial/lesson6/

    在前面的介绍中我们说过,会将后端的内容通过render** 函数将其结果传递给前端对应的对象:

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

    在上一节中,我们提到过,随着用户的每一次访问,或者对交互选项的修改,server 中的内容都会一遍遍的重复运行。

    其中的两个函数作用分别是:

    • getSymbols 获取Yahoo 上的财经数据
    • chartSeries 对内容进行绘图,根据input$log 选项进行调整。

    因此,从以上代码我们可知,随着用户一次次访问,它们会不断的重复运行:从网站爬取数据—绘图。

    显然,如果用户希望对绘图内容进行修改的话,我们并不需要再次从网站爬取一遍数据,我们要做的仅仅只是修改一下绘图函数中的某个或某几个参数。

    这时候就可以使用reactive 函数了:

    1. # Server logic
    2. server <- function(input, output) {
    3. dataInput <- reactive({
    4. getSymbols(input$symb, src = "yahoo",
    5. from = input$dates[1],
    6. to = input$dates[2],
    7. auto.assign = FALSE)
    8. })
    9. output$plot <- renderPlot({
    10. chartSeries(dataInput(), theme = chartTheme("white"),
    11. type = "line", log.scale = input$log, TA = NULL)
    12. })
    13. }

    当我们启动服务时,该函数会将结果返回并保存,后续处理时,我们只需要调用dataInput() 访问该reactive 对象即可。

    通过reactive 函数获取固定数据的好处在于,相比一般R 表达式,它会将结果储存内存中,如果你下一次调用相同的语句(比如每个用户访问shiny 都会循环执行server 对象对应的全部语句),它会直接返回该对象先前保存的结果。

    如果reactive 语句中的内容发生了变化呢?它可不会笨笨地依旧返回先前存储的数据,当它发现数据发生变化后,便会重新计算结果,并进行一次复制,再次将信息存储在reactive 中。

    至于checkboxInput 的使用,我们可以将其值设置为一个默认的选项(T 或者F),通过判断该选项的值,来进行赋值与否(这里还是可以结合reactive 函数):

    1. if (input$adjust) finalInput <- reactive({
    2. adjust(dataInput())
    3. })