shiny cheatsheet:https://shiny.rstudio.com/articles/cheatsheet.html
shiny官网第一节:https://shiny.rstudio.com/tutorial/written-tutorial/lesson1/
shiny是一个用于开发交互APP的R包,通过它,我们可以将写的R代码包装成一个网页APP,用户可以通过与网页交互的方式进行无代码的操作,这样可以节省用户的时间,同时加速开发端与用户端交流的速度。
示例:
library(shiny)
runExample("01_hello")
shiny app的所有代码被写入了一个脚本中,这个脚本主要由三部分组成1、定义用户界面的对象(网页的门面) 2、服务端运行的函数(网页内在运行的逻辑)3、shinyapp() (用于启动ui和server)。
在使用时,需要保证该脚本(app.R)在某个路径(如newdir/)下,通过运行runAPP("newdir)启动应用
在之前的旧版中,ui与server必须分开写入两个脚本(ui.R,server.R),放入一个文件夹内,而在新版中,写在两个脚本和一个脚本中均可,写在一个脚本中可以方便用户启动代码或与别人交流代码。
UI的结构
library(shiny)
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
注:可以发现:page>layout>panel>action module
任何一部分都可以独立成一个结构
server的结构
# Define server logic required to draw a histogram ----
server <- function(input, output) {
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
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")
})
}
注意:我们可以发现,
1、server中的input,都是在ui中起输入功能的module的名字,而output,都是对应ui中起output功能的module的名字,因此,server的本质就是将ui中输入的内容,通过一系列函数变换,转化为我们想要的输出格式
2、为了保证app与用户的交互功能,我们需要在用户更新输入数据时及时响应改变,因此对于变化的内容一般都要用到render*(对于图表)和reactive(对于数据)函数。
?reactive
Wraps a normal expression to create a reactive expression. Conceptually, a reactive expression is a expression whose result will change over time.#将普通的表达式转化成随时间更新的表达式
`reactivePlot` has been replaced by `[renderPlot()](http://114.212.200.51:3838/help/library/shiny/help/renderPlot)`.
`reactiveTable` has been replaced by `[renderTable()](http://114.212.200.51:3838/help/library/shiny/help/renderTable)`.
`reactivePrint` has been replaced by `[renderPrint()](http://114.212.200.51:3838/help/library/shiny/help/renderPrint)`.
`reactiveUI` has been replaced by `[renderUI()](http://114.212.200.51:3838/help/library/shiny/help/renderUI)`.
`reactiveText` has been replaced by `[renderText()](http://114.212.200.51:3838/help/library/shiny/help/renderText)`.
?renderPlot
Renders a reactive plot that is suitable for assigning to an output slot.
我们把上述shiny的特性称为reactivity
image.png
用户可以利用reactivity这类特性做更加灵活的交互展示
image.png
一个shiny-app的基本结构
image.png
输入的action module汇总
actionButton
actionLink
checkboxGroupInput
checkboxInput
dateInput
dateRangeInput
fileInput #如果你想用这个模块,务必读一下它的说明文档,它读进来的是一个list对象!!
numericInput
passwordInput
radioButtons
selectInput
sliderInput
submitButton
textInput
输出的函数汇总(左边是server中的render(等同于reactive+output),右边是ui中的*output函数)
shiny中的panel和layout,用于调整action module的排列方式
image.png
注意!!!一个容易出错的地方!!!多次在这边出问题!
iris_input<-reactive({
input$test
})
output$text2=renderText({iris_input})
#上述为错误案例,正确的为
iris_input<-reactive({
input$test
})
output$text2=renderText({iris_input()})
#解释,reavtive或render*是将普通表达式变成reactive表达式,以一个function的形式返回,因此要加括号!
小技巧1:actionbutton+isolate可以避免reactive频繁刷新
output$mattab<-renderTable({
input$start
isolate(mat()[1:6,1:6])
},rownames = T)
#解释:isolate可以屏蔽mat()反应式改变引起的reactive,而如果input$start改变,则会重新运行 isolate(mat()[1:6,1:6])!
小技巧2:shiny的reactive中存在两个可以帮助你跳出reactive的函数--observeEvent和observe() (注:isolate()是阻止reactive,不是跳出reactive)
observeEvent(input$create.proj,{get_shiny_local(input$proj.name)})
#前一个参数如果发生改变,那么会执行第二个参数的内容,第二个参数可以是reactive表达式,也可以是普通表达式!
#这种情况适用于,我们希望做一些保存或者部分结果不想展示出来的时候
小技巧3:由于actionbutton在使用的时候是由null变化为0,因此如果我们使用{input$actionbutton ;isoloat(expr)},会在shiny启动的时候有报错的小bug(因为此时isolate中的expr都没有赋值,所以会报错),类似下图
image.png
解决这一问题我们可以通过设置actionbutton的取值来解决,如:
if(input$start==0){NULL}else{
chromatogram(seq(), width = 200, height = 2, showcalls = "both")
}
修改后
小技巧4:shiny上传文件是有最大限制的,一般最大为5M,如果超过了会报错,解决办法是在app.r中加入options(shiny.maxRequestSize = 30 * 1024 ^ 2),可以将上传限度调整到30M,依次类推。
参考链接:http://www.dovov.com/shinyx.html
小技巧5:在使用fileinput actionmodule的时候,需要提供接受的文件类型,可以参考下面链接进行填写:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
小技巧6:影响shinyapp与用户交流体验的一大原因是文件的上传和下载,尤其是大文件的上传和下载,因此,这两个过程尽量采取压缩文件的方式进行。如600M的csv文件经过压缩后仅为14M
网友评论