什么是shiny: Shiny 是一个开源的 R 包,它为使用 R 构建 Web 应用提供了一个优雅有力的 Web 框架 。Shiny 帮助R用户在不需要前端知识的条件下将数据分析的结果转变为可交互的 Web 应用。
shiny能够帮助R用户在没有前端,后端知识的情况下,构建web工程,独立,快速的实现web上数据可视化的工作。 学完本课程,同学们可以实现从数据分析,建模,到最后的分享结果,结果展示。
https://liam.shinyapps.io/dashboard/
案例
同学们可以通过这个链接查看我制作的一个shiny案例。 这个案例是一个推荐系统,可以帮助店铺找到某一个商品相似的商品,以及可能对这个商品感兴趣的人。 另外还对商品以及店铺进行了数据分析,并展示
我们通过几个例子开始
我们现来查看一个例子,然后分析其工作原理:
library(shiny)
runExample("01_hello")
example1
这个例子使用的是自带的faithful数据集合,通过改变slider的值调整直方图的bin。
shiny程序包含两个部分:UI部分和server部分,简单的来书,UI部分就是我们需要设定web页面要怎么展示, server 部分就是后台的计算是如何进行。
我们来看一下上面这个程序的源代码:
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# 这里指定的是什么布局方式
sidebarLayout(
# Sidebar panel
sidebarPanel(
# 这里是定义一个slider 作为输入
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# 主页面,这里主页面是一个绘图
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
定义我们UI部分展示的结果是如何计算的
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
shinyApp(ui, server)
我们现在对UI进行一点简单的修改,直接换成一个数值的输入
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# 这里指定的是什么布局方式
sidebarLayout(
# Sidebar panel
sidebarPanel(
# 这里是定义一个slider 作为输入
numericInput(inputId = "bins",
label = "Numeric input",value = 10)
),
# 主页面,这里主页面是一个绘图
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
shinyApp(ui, server)
server <- function(input, output) {
}
shinyApp(ui, server)
大家可以看到,刚才的对应的slider 的位置就变成了一个直接写数字的输入窗口了。 第一个例子大家可能对很对东西都有疑惑,其实这没关系,第一个例子是让大家对 shiny的构建有一个简单的了解。
shiny 程序分为两个部分
这个例子展示了直接打印R对象,以及使用HTML表格显示数据
library(shiny)
runExample("02_text")
shinyexample2
第一个例子展示了使用单个数字输入来调整直方图,这个例子包含了两个输入和两种了类型的输出。
如果同学们观察的仔细的话,同学们可以发现shiny程序最重要的属性,就是输入与输出是实施的连接在一起的 这种情况下,这种交互性,是shiny非常重要的一个特性。
我们来查看一下代码:
# Define UI for dataset viewer app ----
ui <- fluidPage(
# App title ----
titlePanel("Shiny Text"), # 标题
# Sidebar layout with a input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Selector for choosing dataset ----
selectInput(inputId = "dataset",
label = "Choose a dataset:",
choices = c("rock", "pressure", "cars")), # 这是一个选择输入
# Input: Numeric entry for number of obs to view ----
numericInput(inputId = "obs",
label = "Number of observations to view:",
value = 10) # 这是一个数字输入
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Verbatim text for data summary ----
verbatimTextOutput("summary"), # 这是一个输入
# Output: HTML table with requested number of observations ----
tableOutput("view") # 这是一个表格输入
)
)
)
我们来查看一下Server,这个时候Server也变得有一点复杂:
#Define server logic to summarize and view selected dataset ----
server <- function(input, output) {
# Return the requested dataset ----
datasetInput <- reactive({ # 输入
switch(input$dataset,
"rock" = rock, # 对应了不同的数据集合
"pressure" = pressure,
"cars" = cars)
})
# Generate a summary of the dataset ----
output$summary <- renderPrint({ # 输出一个summary,这是一个R对象
dataset <- datasetInput()
summary(dataset)
})
# Show the first "n" observations ----
output$view <- renderTable({ # 另外一个输出
head(datasetInput(), n = input$obs)
})
}
这里我们接触到了输入与输出是的联动性,在具有交互式用户界面的传统程序中,这可能涉及设置事件处理程序和编写代码以读取值和传输数据,shiny是如何处理的,目前还没有仔细讲解其工作的原理,同学们不要担心,接下来的课程会介绍
在之前我们已经了解到shiny 的交互性,使用shiny构建交互程序非常容易,但是为了利用好这一项工具, 需要对其原理有一个简单的了解,在shiny中,有三种对象:
分别称为:反应源,中间件,反应端
反应式编程
shiny交互编程最简单的结构就是反应源直接到反应端
简单结构
在shiny程序中,反应源通常是通过浏览器界面的用户输入,比如之前的案例,比如输入数值调整直方图的bin。
反应端通常出现用户的浏览器,比如一张图或者一个表。
在一个简单shiny程序中:
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs))
})
}
案例
另外我们回到前面的案例
datasetInput <- reactive({ # 输入
switch(input$dataset,
"rock" = rock, # 对应了不同的数据集合
"pressure" = pressure,
"cars" = cars)
})
大家可能还有注意到reactive函数,这个函数用于封装慢速或计算上昂贵的操作
上面就已经涵盖了很多基本的概念,下一节我们要做一个总结,然后开始从0到1开始构建一个shiny程序
回顾我们课程,我们是如何实现一个shiny的web程序:
UI部分 | server部分 |
---|---|
dataTableOutput | renderDataTable |
imageOutput | renderImage |
plotOutput | renderPlot |
verbatimTextOutput | renderPrint |
tableOutput | renderTable |
textOutput | renderText |
uiOutput | renderUI |
htmloutput | renderUI |
介绍几个主要的输入:
actionButton
actionButton(inputId = '按钮',label = '按钮')
checkboxGroupInput
checkboxGroupInput(inputId = '选择框',label = '选择框',choices = c('a','b','c'))
3. checkboxInput
checkboxInput(inputId = '勾选框',label = '勾选框',value = TRUE)
dateInput
dateInput(inputId = '时间输入',label = '时间输入')
dateRangeInput
dateRangeInput(inputId = '时间范围输入',label = '时间范围输入',start = 1,end = 100)
numericInput
numericInput(inputId = '数字输入',label = '数字输入',value = 100)
textInput
textInput(inputId = '文本输入',label = '文本输入')
主要的输出:
dataTableOutput
output$a = renderDataTable({
head(iris)
})
dataTableOutput(outputId = 'a')
plotOutput
output$b = renderPlot({
plot(iris$Sepal.Length,iris$Sepal.Width)
})
plotOutput(outputId = 'b')
打开Rstudio,点击file,创建一个shiny app
使用的数据数据是,ggplot里面自带的数据diamonds,绘制不同的直方图:
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(ggplot2)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Diamond data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "x",label = 'x',choices = names(diamonds)[c(1,5,6,7,8,9,10)],
selected = T),
selectInput(inputId = "y",label = 'y',choices = names(diamonds)[c(1,5,6,7,8,9,10)],
selected = T)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("diamondplot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$diamondplot <- renderPlot({
# generate bins based on input$bins from ui.R
plot(x = diamonds[[input$x]],y = diamonds[[input$y]],xlab = 'x',ylab = 'y')
})
}
# Run the application
shinyApp(ui = ui, server = server)
需要联系我可以添加我的微信