在上一節「R shiny基礎」交互式入門, 我們實現了簡單的用戶交互。這一篇將會在之前的基礎上,以對美國的人口普查結果進行可視化為例講解如何通過從外部加載數據和腳本,實現更加復雜的操作。
加載數據和腳本
在app.R的同級路徑下創建"census-app"文件夾。之后進入該文件夾創建data文件夾,之后下載counties.rds數據到此文件夾中
用readRDS
讀取rds類型數據,數據內容為州名、人口數,不同種群人的比例。
conties <- readRDS("census-app/data/counties.rds")
下載helpers.R和app.R同級,該腳本用于從之前的數據中進行繪圖。鑒于該腳本依賴于maps
和mapproj
這兩個R包,你需要在使用之前進行安裝。
用source
加載R腳本,以及用library依賴包
library(map)
library(mapproj)
source("census-app/helpers.R")
腳本里面就一個percent_map
函數,支持五個參數,分別為可視化列,顏色,標題,陰影大小下限,陰影大小上限。
percent_map(counties$white, "darkgreen", "% White")
效果圖如下:
可視化結果
代碼執行
在shiny應用中,不同部分的代碼的執行次數不同,規律如下:
- 啟動應用時,Shiny會運行一次所有的代碼
- 每有一個新的用戶運行你的shiny應用,就會運行一次
server
函數,保證每個用戶有不同的響應式對象(reactivate object) - 每次用戶進行交互時,render部分的代碼都會運行一次
因此,對于數據加載和代碼加載的代碼應該放在server
函數外,僅僅將那些用戶交互時才需要發生變更的代碼放在render函數的表達式中。
結果
現在,我們就可以構建出一個能夠根據用戶選擇,然后展示結果的Shiny應用了。
版本一:
library(shiny)
library(maps)
library(mapproj)
source("census-app/helpers.R")
counties <- readRDS("census-app/data/counties.rds")
ui <- fluidPage(
titlePanel("censusVis"),
sidebarLayout(
sidebarPanel(
helpText("Create demographic maps with
information from the 2010 US Census."),
selectInput("var",
label = "Choose a variable to display",
choices = c("Percent White" = "white",
"Percent Black" = "black",
"Percent Hispanic" = "hispanic",
"Percent Asian" = "asian"),
selected = "Percent White"),
sliderInput("range",
label = "Range of interest:",
min = 0, max = 100, value = c(0, 100))
),
mainPanel(
plotOutput(outputId = "selectVar")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$selectVar <- renderPlot({
percent_map(counties[,input$var],
"darkgreen",
paste0("% ", input$var),
input$range[1],
input$range[2])
})
}
}
# Run the application
shinyApp(ui = ui, server = server)
版本二:在表達式中用switch函數,而不是在selectInput定義鍵值關系
...
selectInput("var",
label = "Choose a variable to display",
choices = c("Percent White", "Percent Black",
"Percent Hispanic", "Percent Asian"),
selected = "Percent White")
...
server <- function(input, output) {
output$map <- renderPlot({
data <- switch(input$var,
"Percent White" = counties$white,
"Percent Black" = counties$black,
"Percent Hispanic" = counties$hispanic,
"Percent Asian" = counties$asian)
legend <- switch(input$var,
"Percent White" = "% White",
"Percent Black" = "% Black",
"Percent Hispanic" = "% Hispanic",
"Percent Asian" = "% Asian")
percent_map(data, "darkgreen", legend, input$range[1], input$range[2])
})
}
版本三: 用do.call
簡化版本二的代碼。
server <- function(input, output) {
output$map <- renderPlot({
args <- switch(input$var,
"Percent White" = list(counties$white, "darkgreen", "% White"),
"Percent Black" = list(counties$black, "black", "% Black"),
"Percent Hispanic" = list(counties$hispanic, "darkorange", "% Hispanic"),
"Percent Asian" = list(counties$asian, "darkviolet", "% Asian"))
args$min <- input$range[1]
args$max <- input$range[2]
do.call(percent_map, args)
})
}
總結
這一節學習了
- 在Shiny應用中加載數據和代碼
- Shiny應用不同部分代碼的運行次數
-
Switch
函數和selectInput
通常一塊使用。
下一節主要學習構建模塊化,快速運行的Shiny應用的一些技巧。
傳送門
Shiny基礎教程: