参见:https://shiny.rstudio.com/tutorial/written-tutorial/lesson4/
前面的内容我们一直都是在围绕ui 内容展开。但是,即使ui 设计的再漂亮,就像是光鲜亮丽的空壳,它的内在还是毫无内容的。
这样的产品对于用户来说,是毫无意义。
我们如何能够将R 中存储的内容,比如数据框,比如图像,绘图展示在ui 界面呢?
因此,下面我们要学会编写server 部分,通过设计不同的内容,实现与ui 中交互元素的联系。
相比之前,我们首先还是需要设计不同的ui,接着就是通过sever 部分控制输出了。
1. 基本的输出类型
还是和交互工具一样,shiny 也提供了很多的内置函数,用来输出不同类型的内容:
| Output function | Creates |
|---|---|
dataTableOutput |
DataTable |
htmlOutput |
raw HTML |
imageOutput |
image |
plotOutput |
plot |
tableOutput |
table |
textOutput |
text |
uiOutput |
raw HTML |
verbatimTextOutput |
text |
2. server 中设置对象输出
ui 的目的是告诉shiny 把什么东西放在页面的什么位置,而server 则是用来构建这个东西。
server 对象中的output 是一个类似列表类型的对象:
server <- function(input, output) {output$selected_var <- renderText({"You have selected this"})}
需要注意的是,这里output 中定义的对象名,需要与ui 中的对象一致。
同样对应ui 中的几个输出类型,shiny 也提供了几个对应的server 中的函数:
| render function | creates |
|---|---|
renderDataTable |
DataTable |
renderImage |
images (saved as a link to a source file) |
renderPlot |
plots |
renderPrint |
any printed output |
renderTable |
data frame, matrix, other table like structures |
renderText |
character strings |
renderUI |
a Shiny tag object or HTML |
比如下图是我展示的一个表格:
# some var ----------------------------------------------------------------test_df <- head(test_df_all)# Define UI ----ui <- fluidPage(titlePanel("widgets tests"),sidebarLayout(sidebarPanel(p("blablabla~"),selectInput("select", strong("Select one to display"),choices = list("Percent White" = 1, "Choice 2" = 2,"Choice 3" = 3), selected = 1),sliderInput("slider1", strong("range your intrests"),min = 0, max = 100, value = 100)),mainPanel(dataTableOutput("test_df"))))# Define server logic ----server <- function(input, output) {output$test_df <- renderDataTable({test_df})}# Run the app ----shinyApp(ui = ui, server = server)

需要注意的是,render函数家族的使用,其内部必须用{} 包围语法。
如:output$test_df <- renderDataTable({test_df})
3. server 中设置接受输入
不难发现,server 中默认有两个形参,我们只是使用了output,而input,则可以用来接受外部的一些信息。
我们可以直接在output 的内部使用它,比如定义一个selected_var 元素,其内容为输出select 交互元素的内容:
# Define UI ----ui <- fluidPage(titlePanel("widgets tests"),sidebarLayout(sidebarPanel(p("blablabla~"),selectInput("select", strong("Select one to display"),choices = list("Herb info", "ingredient info"))),mainPanel(textOutput("selected_var"),dataTableOutput("test_df"))))# Define server logic ----server <- function(input, output) {output$selected_var <- renderText({paste("You have selected", input$select)})output$test_df <- renderDataTable({test_df})}
当我们切换selectInput 交互选项时,输出的内容也随之发生了改变:

ps:如果是sliderInput 内容,可以通过切片获得其内部元素:
output$min_max <- renderText({paste("You have chosen a range that goes from",input$range[1], "to", input$range[2])})
疑惑:
可是,如果想要通过切换选项来变换数据框或图像,该如何操作呢?
发现并不可以简单的通过sever 中的内容来解决。比如将表格包装在一个列表中,通过接受input 返回的值来获取列表名称对应的数据框获取:
test_df <- head(test_df_all)tail_df <- tail(test_df_all)test_list <- list("Herb info" = test_df, "ingredient info" = tail_df)# Define UI ----ui <- fluidPage(titlePanel("widgets tests"),sidebarLayout(sidebarPanel(p("blablabla~"),selectInput("select", strong("Select one to display"),choices = list("Herb info", "ingredient info"))),mainPanel(dataTableOutput("test_df"),textOutput("test_txt"))))# Define server logic ----server <- function(input, output) {output$test_df <- renderDataTable({test_list$`input$select`})output$test_txt <- renderText({paste0("output is ", input$select)})}

