应用的格式和启动
你也许注意到了,Shiny应用的定义和启动方式有不止一种。有的时候你会在server.R文件里看到shinyServer(),同样也会在ui.R文件里看到shinyUI()。有的时候却根本找不到server.R文件。
本文概述了定义和启动Shiny应用的不同方法。
server.R和ui.R文件
大多数早期的Shiny样例中会包含一个server.R文件和一个ui.R文件,比如下面这个:
## server.R ##
function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
}
## ui.R ##
fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
)
对于以这种方式定义的应用,server.R文件必须返回一个server函数,ui.R文件必须返回一个UI对象(本例中的UI对象是由fluidPage()创建的)。换句话说,如果文件中包含其他代码(比如公共函数(utility function)),你就必须保证这个文件最后的语句是server函数或者UI对象。
要想更深入的了解这方面内容,请参看这个关于 双文件应用 的文章。
shinyServer()和shinyUI()
对于Shiny 0.10之前的版本,server.R和ui.R分别需要调用shinyServer()和shinyUI()。稍早的Shiny应用样例看起来也许会是下面这样。它们其实和之前的例子是一样的,只有一点,在下面的例子里,代码被放在shinyServer()和shinyUI()里了:
## server.R ##
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
})
## ui.R ##
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
))
至于Shiny 0.10之后的版本,就不需要再这样做了。
app.R
Shiny 0.10.2版本就可以在一个文件里创建应用了——app.R,这个文件同时包含了UI和server代码。它必须返回一个由shinyApp()函数创建的对象。
## app.R ##
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
This method is more appropriate for smaller applications; for larger applications, you may find that having separate ui.R
and server.R
files makes your code easier to manage.
这个办法对于体量较小的应用更为合适;对于体量较大的应用,使用双文件(ui.R和server.R)会更方便。
session和clientData(参数)
在一些样例的server代码中,你也许会看到这样的代码:
function(input, output) { .... }
在其他的一些例子里,你也许会在server function里看到第三个叫做session的参数:
function(input, output, session) { .... }
这个session参数是可选的,仅当你想要使用高级Shiny特性的时候才使用它——有些Shiny函数会将session变量当作一个参数。
同样地,你也许在一些旧样例中看到server function把clientData当作参数。clientData提供了连接和web页面上元素可见性的信息(详见 clientdata)。
但是现在已经不需要clientData这个参数了,因为你可以通过session的session$clientData参数实现同样的功能。为了代码的连贯性,我们推荐你使用session$clientData参数。
# These two server functions do the same thing
# 这两个server functions 的功能是一样的
# Using the clientData argument directly (older examples)
# 直接使用clientData参数(旧例)
function(input, output, clientData) {
output$txt <- renderPrint({
clientData
})
}
# Using the session argument
# 使用session参数
function(input, output, session) {
output$txt <- renderPrint({
session$clientData
})
}
调用runApp()的方法
这几样东西也许会在启动一个应用的时候被传输到runApp()中。
App目录
如果你的应用在目录 myapp/ 下,你可以这样启动它:
runApp("myapp")
Shiny app对象
如果你在控制台使用shinyApp()创建了一个app对象,你可以将这个对象传给runApp():
# Create app object (assume ui and server are defined above)
app <- shinyApp(ui, server)
runApp(app)
此外,如果你只是在控制台写下应用然后按回车键,R一样会启动这个应用。这是因为当你在控制台运行代码的时候,R会调用print()来显示返回值,对于Shiny app对象,print()方法会调用runApp()。所以你可以这样来启动应用:
app <- shinyApp(ui, server)
app
list(ui,server)
另一个启动应用的方法是传递给runApp()一个包含ui和server组件的列表(list)。这是上面的Shiny app对象方法的旧形式。
# (Assume ui and server are defined above)
runApp(list(ui, server))