Shiny学习笔记:简介
简介
Shiny app主要包括两个关键组件:
- UI(user interface):定义app外观
- server:定义app如何运行
创建
建议在Rstudio中运行。 先安装shiny
包:
install.packages("shiny")
library(shiny)
有好几种创建Shiny app
的方式,最简单的就是新建一个文件夹,在里面创建一个app.R
文件,里面写入代码,定义app外观以及如何运行
library(shiny) #加载shiny包
ui <- fluidPage(
"Hello, world!"
) #定义ui,这里是一个界面显示Hello, World!
server <- function(input, output, session) {
} #定义app如何运行,这里是空的,不做任何事情
shinyApp(ui, server) #创建并启动app
点击Rstudio中的Run App
按钮,app
就运行了,显示如下:
这样我们就创建了一个最简单的app
了。
控件
控件可以让用户界面更丰富,下面我们添加一个选择
控件, 将ui修改如下:
ui <- fluidPage(
selectInput("dataset", label = "Dataset", choices = ls("package:datasets")),
verbatimTextOutput("summary"),
tableOutput("table")
)
fluidPage()
:布局函数,定义界面显示方式selectInput()
:输入控件,用户可以提供输入值,这里是选择输入控件,用户可以选择包datasets
中的数据集verbatinTextOutput()
以及tableOutput()
:输出控件
app
运行之后显示如下:
设置服务端
上面app
服务端一直是空白的,用户无论如何选择数据集,界面都没结果显示,下面我们添加部分服务端代码。shiny
使用的是响应式编程,我们只是告诉shiny
如何运行计算,不是让shiny
直接去做,直白的说就是我们只是提供shiny
食谱,不是让shiny
直接做菜。
下面的小例子,我们告诉shiny
如何填充输出部分,将server
部分修改如下:
server <- function(input, output, session) {
output$summary <- renderPrint({
dataset <- get(input$dataset, "package:datasets")
summary(dataset)
})
output$table <- renderTable({
dataset <- get(input$dataset, "package:datasets")
dataset
})
}
基本上所有的输出都是下面的模式:
output$ID <- renderTYPE({
# Expression that generates whatever kind of output
# renderTYPE expects
})
output$ID
对应于ui
中设置的输出ID
,必须一一对应,不然出错。render
函数则是渲染
我们提供的代码,这里renderPrint()
打印出summary
的结果,renderTable
输出数据集。每一个render*
函数对应于一种特定的输出,上面的renderPrint()
捕获并显示数据集的信息,renderTable()
则是直接显示该数据集。
运行上面的app
,显示界面如下:
由于是响应式编程,所以一旦我们选择不同的数据集,输出结果自动变换,比如我们选择另外一个数据集,结果就不同:
精简代码
即使是上面这样最简单的app
,我们发现是还是存在重复的脚本:
dataset <- get(input$dataset, "package:datasets")
重复代码对于app
的运行、维护、资源都是一种负担,在shiny
中我们尽量使用响应表达式(reactive expression
)来精简代码。reactive expression
用reactive({})
封装代码并赋值给一个变量,它只在启动app
的时候运行并将结果缓存,将server
修改如下:
server <- function(input, output, session) {
dataset <- reactive({
get(input$dataset, "package:datasets")
})
output$summary <- renderPrint({
summary(dataset())
})
output$table <- renderTable({
dataset()
})
}
可以看到dataset
我们只获取了一次,但是使用了两次,值得注意的是一旦变量经reactive({})
之后,变量后面作为一个函数一样使用。
这里只讲了一些很简单的控件,实际上shiny
存在十分丰富的控件,RStudio提供了一份
shiny小抄
,大家可以打印出来,没事的时候看看。
参考:https://mastering-shiny.org/basic-app.html