Shiny学习笔记:响应式编程-1

简介

前面主要学习的是用户前段UI,现在开始将学习服务端,这是用户不可见的Shiny部分,Shiny服务端利用的是响应式编程(Reactive Programming),这是一种优美的、强大的编程范式,但是也是容易让人迷惑的。Reactive Programming的核心是指定从属关系,当输出变化时,所有与其相关的输出将自动变化。这使得Shiny App变得流畅。

server()函数

一个Shiny App的框架如下:

library(shiny)

ui <- fluidPage(
  # front end interface
)

server <- function(input, output, session) {
  # back end logic
}

shinyApp(ui, server)

UI相对来说是很简单的,所有用户看到都是同样的前端界面,但是server端不一样,每个的用户都需要一份app拷贝,不同用户之间互不干扰。

为了实现这种独立性,Shiny在每一个session启动的时候会调用一次server()函数。当server()函数被调用的时候,会创建一个独立的本地环境,这可以保证每一个session都有其独一无二的状态,可以隔离函数内部创建的变量,所以你会发现几乎所有的reactive programming都是在server()函数内部。

server()函数有三个参数:inputoutputsession

Input

input类似于一个list,包含用户在浏览器传递的数据,举个例子,如果UI含有一个数值输入count

ui <- fluidPage(
  numericInput("count", label = "Number of values", value = 100)
)

那么你获取的数据就是input$count,它的初始值为100, 当用户改变值的时候,input$count值自动同步改变。input是只读对象,如果在server()函数内部修改input会报错:

server <- function(input, output, session) {
  input$count <- 10  
}

shinyApp(ui, server)
#> Error: Attempted to assign value to a read-only reactivevalues object

input会有选择性地允许谁可以读取它,要读取input中的值,必须是由renderText(),reactive()等类似函数创建的reactive context

server <- function(input, output, session) {
  message("The value of input$count is ", input$count)
}

shinyApp(ui, server)
#> Error: Operation not allowed without an active reactive context. 
#> (You tried to do something that can only be done from inside 
#> a reactive expression or observer.)

Output

input类似,区别是output传递输出,input接收输入。output往往是与render函数一起。

ui <- fluidPage(
  textOutput("greeting")
)

server <- function(input, output, session) {
  output$greeting <- renderText("Hello human!")
}

render函数做两件事:

  • 它指定了output与对应的input
  • R代码转化为HTML
Researcher

I am a PhD student of Crop Genetics and Breeding at the Zhejiang University Crop Science Lab. My research interests covers a range of issues:Population Genetics Evolution and Ecotype Divergence Analysis of Oilseed Rape, Genome-wide Association Study (GWAS) of Agronomic Traits.

comments powered by Disqus