「R」Shiny:用户界面(一)输入控件

2020-07-06 17:52:24 浏览数 (1)

前面几篇文章我们构建了一个简易的 Shiny 应用,如果我们仔细观察过没有几行的实现代码就知道 Shiny 将前端(实现用户界面)和后端(服务逻辑)进行了分离,这让我们可以比较独立地来看待它们。接下来的几篇文章会关注前端,探索 Shiny 提供的 HTML 输出、输出和页面布局功能。

首先依旧载入 Shiny。

代码语言:javascript复制
library(shiny)

输入控件的通用结构

所有的输入(控件)函数第 1 个参数都是相同的 inputId。它是用来连接前端和后端的标识符(ID):如果你的 UI 有一个输入控件的 ID 是 "name",那么你可以在后端中使用 input$name 访问它

inputId 有两处限制:

  • 必须是合法的变量名。
  • 必须唯一。

大多数的输入函数的第 2 个参数是 label,它用于为控件创建可读的标签。它就没有限制了,尽量让大家看得懂该控件的含义即可。

第 3 个参数一般是 value,它用于设定默认的控件值。

其他的参数一般每个控件都不太相同,需要根据情况和文档说明进行设定。

根据上面的介绍,我们一般在实际使用时会忽略第一个和第二个参数名,如:

代码语言:javascript复制
sliderInput("min", "Limit (minimum)", value = 50, min = 0, max = 100)

下面将大体根据创建的控件类型介绍内建于 Shiny 包的输入控件函数,目的是帮助各位读者快速地对整体的功能有所了解,而不是详细地描述所有的参数。如果你想要了解每个输入函数的详情,请阅读相应的函数文档。

自由文本

这里介绍 3 个函数用于文本的输入。

代码语言:javascript复制
ui = fluidPage(
  ## 适用于少量文本
  textInput("name", "What's your name?"),
  ## 适用于密码
  passwordInput("password", "What's your password?"),
  ## 适用于成段文本
  textAreaInput("story", "Tell me about yourself", rows = 3, cols = 80)
)

server = function(input, output, session) {
  
}

shinyApp(ui, server)

如果你想要确保文本含有指定的属性,可以使用 validate() 函数(后续内容会介绍)。

数值输入

如果想要收集数值型数据,使用 sliderInput() 创建 1 个滑块,或使用 numericInput() 创建一个受限文本框。当 silerInput()value 参数值长度为 2 时,会产生一个范围滑块。

代码语言:javascript复制
ui = fluidPage(
  ## 创建
  numericInput("num", "Number one",
               value = 0, min = 0, max = 100),
  ## 创建简单滑块
  sliderInput("num2", "Number two",
              value = 50, min = 0, max = 100),
  ## 创建范围滑块
  sliderInput("rng", "Range",
              value = c(10, 20), min = 0, max = 100)
)

shinyApp(ui, server)

一般当数值不那么重要时使用滑块,因为滑动选择一个指定值的体验比较糟糕。

自定义滑块,请阅读:https://shiny.rstudio.com/articles/sliders.html

日期

使用 dataInput() 创建单个日期,使用 dateRangeInput() 创建日期范围。参数 datesdisableddaysofweekdisabled 允许我们对合理输入进行限制。

代码语言:javascript复制
ui = fluidPage(
  ## 创建单个日期
  dateInput("dob", "When were you born?"),
  ## 创建日期范围
  dateRangeInput("holiday", "When do you want to go on vacation next?")
)

shinyApp(ui, server)

默认的日期格式、语言等使用的是美国标准,它们可以通过参数 formatlanguageweekstart 等进行修改。

代码语言:javascript复制
ui = fluidPage(
  dateInput("dob", "When were you born?", language = "zh-CN"),
  dateRangeInput("holiday", "When do you want to go on vacation next?", language = "zh-CN")
)

shinyApp(ui, server)

选择列表

selectInput()radioButtons() 是两种不同的创建选择列表方法。

代码语言:javascript复制
animals = c("dog", "cat", "mouse", "bird", "other", "I hate animals")

ui = fluidPage(
  selectInput("state", "What's your favourite state?", choices = state.name),
  radioButtons("animal", "What's your favourite animal?", choices = animals)
)

shinyApp(ui, server)

单选按钮有两个很好的特点:

  • 展示了所有可能选项,非常适用于短列表
  • 可以展示非文字的内容,如表情
代码语言:javascript复制
ui = fluidPage(
  radioButtons("rb", "Choose one:",
               choiceNames = list(
                 icon("angry"),
                 icon("smile"),
                 icon("sad-tear")
               ),
               choiceValues = list("angry", "happy", "sad")
  )
)

shinyApp(ui, server)

使用 selectInput() 创建的下拉列表由于所占的空间固定,非常适用于长列表。如果设定了 multiple = TRUE,还支持多选。

代码语言:javascript复制
ui <- fluidPage(
  selectInput(
    "state", "What's your favourite state?",
    choices = state.name,
    multiple = TRUE
  )
)

shinyApp(ui, server)

如果想要使用按钮创建多选列表,需要用到 checkboxGroupInput()

代码语言:javascript复制
ui = fluidPage(
  checkboxGroupInput("animal", "What's your favourite animal?",
                     choices = animals)
)

shinyApp(ui, server)

如果你想要一个应对 Yes/No 问题的复选框,使用 checkboxInput()

代码语言:javascript复制
ui = fluidPage(
  checkboxInput("cleanup", "Clean up?", value = TRUE),
  checkboxInput("shutdown", "Shutdown?")
)

shinyApp(ui, server)

文件上传

使用 fileInput() 设定文件上传。

代码语言:javascript复制
ui = fluidPage(
  fileInput("upload", NULL)
)

shinyApp(ui, server)

文件上传需要后端进行特殊的处理,这会在后面的内容中介绍。如果你里面想要用到它,不妨参考 https://github.com/rstudio/shiny-examples/blob/master/009-upload/app.R 提供的示例 Shiny App。

动作按钮

该特性使用 actionButton()actionLink() 实现,它一般配对后端的 observeEvent()eventReactive() 使用,后续介绍。

代码语言:javascript复制
ui = fluidPage(
  actionButton("click", "Click me!"),
  actionButton("drink", "Drink me!", icon = icon("cocktail"))
)

shinyApp(ui, server)

0 人点赞