在上一节「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基础教程:
- 「R shiny 基础」初识Shiny
- 「R shiny 基础」如何进行网页布局
- 「R shiny基础」增加一些小控件
- 「R shiny基础」交互式入门
- 「R shiny基础」在shiny应用中加载数据和脚本
- 「R shiny基础」reactive让shiny应用运行速度变快
- 「R shiny基础」使用shinyapp分享你的Shiny应用