Shiny Workshop
Denny Chen
deny20700@gmail.com
What is Shiny?
Shiny 讓我們直接用 R 語言撰寫網頁的前後端,並提供圖表接口,讓我們能直接將 R 產生的圖表呈現在網頁上。最基本的 Shiny 專案包含了兩個部份:
-
ui.R — 前端程式碼,描述我們的專案網頁要怎樣呈現與排版
-
server.R — 後端程式碼,負責分析、計算與繪製圖表,並將結果傳遞給前端。
Shiny 並不負責圖表的計算,但他為我們隱藏了網頁互動與設計的細節,並內建了各種表單元件,讓我們可以直接透過 R 的語法來設置元件並利用來達成互動效果。
CONCEPT
Shiny 就像是一間餐廳
先搞懂開餐廳需要什麼吧!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104829/retautant.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104821/output.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104808/back-end.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104817/menu.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104811/front-end.png)
用餐區(前場)
廚房(後場)
菜單
點餐
餐點
傳訂單到廚房
做餐
送到客人手中
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7011656/shiny_logo.png)
Shiny 就是這樣運作的!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104829/retautant.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104829/retautant.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104817/menu.png)
店面+菜單
廚房
餐點
訂單
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104816/order.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104808/back-end.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104821/output.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104830/shiny_demo.gif)
ui.R
input$tag
output$tag
server.R ?
開始之前
- 安裝Shiny套件了嗎?
- 目前有不清楚的地方嗎?
install.packages("shiny")
![](https://media3.giphy.com/media/75yYfqYy5tmHm/giphy.gif)
Let's Go!
![](https://media1.giphy.com/media/dWlWuTFzXbBXtcpKXF/giphy.gif)
CREATE
蓋一家餐廳吧!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104809/create_shiny.gif)
別急!
library(shiny)
ui <- fluidPage("Hello, Shiny !")
server <- function(input, output) {}
# Run the application
shinyApp(ui = ui, server = server)
ui <- fluidPage("Hello, Shiny !")
server <- function(input, output){}
前場(用餐區)
後場(廚房)
fluidPage
一種動態網頁格式
地板鋪好了! 我們有了一間餐廳!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104829/retautant.png)
![](https://media0.giphy.com/media/lPY5d1vUYBreWtF1I0/giphy.gif)
UI
ui.R 門面很重要
U I
ser nterface
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104820/pasted-from-clipboard.png)
Layout
input
Output
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
sidebarLayout()
sidePanel
mainPanel
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104820/pasted-from-clipboard.png)
Layout
Input
Output
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
Layout
Input
Output
Input Syntax
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104815/input_syntax.png)
Output Format
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104819/output_format.png)
Output Syntax
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104818/output_syntax.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104821/output.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104808/back-end.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104817/menu.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104811/front-end.png)
用餐區(前場)
廚房(後場)
菜單
點餐
餐點
傳訂單到廚房
做餐
送到客人手中
SERVER
server.R 規畫你的廚房
廚房
server <- function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
3 rules
Use to write the server function
1. 記得你的Output$tag
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output){ }
output$displot <-
# code
output$tag
output
2. 用render*()輸出
render*()
server <- function(input, output){ }
output$displot <-
renderPlot({
output
})
2. 用render*()輸出
render*()
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104826/render_format.png)
2. 用render*()輸出
render*()
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104827/render_syntax.png)
2. 用render*()輸出
render*()
server <- function(input, output){ }
output$displot <-
renderPlot({
output
})
title <- "100 random normal values" hist(rnorm(100), main = title)
server <- function(input, output){ }
output$displot <-
renderPlot({
output
})
hist(rnorm(
input$num
))
3. 輸入
input
值
sliderInput(inputId =
"num"
,...)
ui <- fluidPage(...
)
3. 輸入
input
值
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104813/input_values.png)
輸入值會隨使用者更換而改變
input$num
renderPlot({
hist(rnorm(input$num))
})
回顧一下
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104824/recall.png)
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
UI
SERVER
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104823/plot_result.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104832/slidebar.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104821/output.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104808/back-end.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104817/menu.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104811/front-end.png)
用餐區(前場)
廚房(後場)
菜單
點餐
餐點
傳訂單到廚房
做餐
送到客人手中
GIVE A TRY
練習一下吧!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104834/Tryit.gif)
調整顏色
調整品種
標題隨品種改變
1. 想想看ui需要放什麼東西?
2. 想想看那server要調整那些東西?
可能會需要用到的材料
解答
解答
library(shiny)
library(tidyverse)
ui <- fluidPage(
# Application title
titlePanel("Try it !"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("color", label = h3("Select Color"),
choices = list("hotpink" = "hotpink",
"darkcyan" = "darkcyan",
"khaki" = "khaki",
"azure" = "azure",
"blueviolet" = "blueviolet"),
selected = "hotpink"),
selectInput("species", label = h3("Select Species"),
choices = list("setosa" = "setosa",
"versicolor" = "versicolor",
"virginica" = "virginica"),
selected = "setosa")
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$distPlot <- renderPlot({
ggplot(data=iris %>% filter(Species == input$species ), aes(x=Sepal.Width))+
geom_histogram(binwidth=0.2, color="black", fill= input$color) +
xlab("Sepal Width") + ylab("Frequency") +
ggtitle(paste0("Histogram of ", input$species ,"'s Sepal Width"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
DEPLOYMENT
開張大吉
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104833/use_shinyapp.png)
若想發布Shiny App則需要申請帳號
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104825/publish.gif)
請先至
申請帳號
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1158770/images/7104872/pasted-from-clipboard.png)
ADVANCED
開間高檔餐廳
![](https://media0.giphy.com/media/3o6ozkQbdfOIyCC6wU/giphy.gif)
![](https://media3.giphy.com/media/Ga2QjY24XSSha/giphy.gif)
![](https://media0.giphy.com/media/3ohs4ukRPFvK1qqvQY/giphy.gif)
豪華的餐廳店面
美味的食物
有效率的廚房
美味的食物-互動式視覺化
有效率的廚房-節省資源
豪華的餐廳店面-Dashboard
THANK
YOU
Denny Chen
deny20700@gmail.com
Shiny Workshop
By Chen Ta Hung
Shiny Workshop
- 41