参见:https://shiny.rstudio.com/tutorial/written-tutorial/lesson6/
在前面的介绍中我们说过,会将后端的内容通过render**
函数将其结果传递给前端对应的对象:
server <- function(input, output) {
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)
})
}
在上一节中,我们提到过,随着用户的每一次访问,或者对交互选项的修改,server 中的内容都会一遍遍的重复运行。
其中的两个函数作用分别是:
- getSymbols 获取Yahoo 上的财经数据
- chartSeries 对内容进行绘图,根据input$log 选项进行调整。
因此,从以上代码我们可知,随着用户一次次访问,它们会不断的重复运行:从网站爬取数据—绘图。
显然,如果用户希望对绘图内容进行修改的话,我们并不需要再次从网站爬取一遍数据,我们要做的仅仅只是修改一下绘图函数中的某个或某几个参数。
这时候就可以使用reactive 函数了:
# Server logic
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)
})
}
当我们启动服务时,该函数会将结果返回并保存,后续处理时,我们只需要调用dataInput()
访问该reactive
对象即可。
通过reactive 函数获取固定数据的好处在于,相比一般R 表达式,它会将结果储存内存中,如果你下一次调用相同的语句(比如每个用户访问shiny 都会循环执行server 对象对应的全部语句),它会直接返回该对象先前保存的结果。
如果reactive 语句中的内容发生了变化呢?它可不会笨笨地依旧返回先前存储的数据,当它发现数据发生变化后,便会重新计算结果,并进行一次复制,再次将信息存储在reactive 中。
至于checkboxInput 的使用,我们可以将其值设置为一个默认的选项(T 或者F),通过判断该选项的值,来进行赋值与否(这里还是可以结合reactive 函数):
if (input$adjust) finalInput <- reactive({
adjust(dataInput())
})