Shiny

介绍

如果你是一个R用户,你可能已经熟悉了Shiny,这是一个使你能够轻松使用R构建交互式网页应用的包。

在使用Knitr计算引擎时,Quarto文档可以包含嵌入的Shiny组件(例如,带有控制其输入的滑块的图表),甚至可以是包含多个组件的简单Shiny应用程序。

本节涵盖将Shiny与Quarto集成,并假设你已经对Shiny有基本的了解。要了解更多关于Shiny的信息,请访问https://shiny.rstudio.com

为了运行下面的示例,你需要最新版本的rmarkdown包(v2.10),你可以通过以下方式安装:

 install.packages("rmarkdown")

你好,Shiny

例如,这是一个包含“老忠实”数据集图表的文档,并带有一个控制箱数的滑块:

这里是这个示例的源代码:

---
title: "Old Faithful"
format: html
server: shiny
---

```{r}
sliderInput("bins", "Number of bins:", 
            min = 1, max = 50, value = 30)
plotOutput("distPlot")
```

```{r}
#| context: server
output$distPlot <- renderPlot({
  x <- faithful[, 2]  # Old Faithful Geyser data
  bins <- seq(min(x), max(x), length.out = input$bins + 1)
  hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
```

这个文档与普通静态文档有两个重要区别:

  1. 文档选项中包含server: shiny,这指示Quarto在文档后面运行一个Shiny服务器:

    ---
    title: "Old Faithful"
    format: html
    server: shiny
    ---
  2. 第二个代码块中包含了context: server选项,这表明这段R代码在Shiny服务器内运行(这段代码通常放在server.R中):

    ```{r}
    #| context: server
    ```

我们将在关于运行文档的文章中介绍如何运行和部署带有Shiny组件的Quarto文档。在此之前,让我们先看一个更深入的示例。

自定义布局

这里是一个包含多个输入以及更类似应用的页面布局(带有侧边栏)的示例:

这里是这个示例的源代码:

---
title: "Iris K-Means Clustering"
format: 
  html:
    page-layout: custom
server: shiny
---

```{r}
#| panel: sidebar
vars <- setdiff(names(iris), "Species")
selectInput('xcol', 'X Variable', vars)
selectInput('ycol', 'Y Variable', vars, selected = vars[[2]])
numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
```

```{r}
#| panel: fill
plotOutput('plot1')
```

```{r}
#| context: server
selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })

clusters <- reactive({
  kmeans(selectedData(), input$clusters)
})

output$plot1 <- renderPlot({
  palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
    "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))

  par(mar = c(5.1, 4.1, 0, 1))
  plot(selectedData(),
       col = clusters()$cluster,
       pch = 20, cex = 3)
  points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
```

在这个示例中有几点值得注意:

  1. YAML前言包含了page-layout: custom选项(以指示我们希望内容占据整个页面,而不是居中且带有填充)。
  2. 我们在定义用户界面的两个代码块中添加了panel: sidebarpanel: fill,以指定我们希望它们布局在特殊的面板容器中。
  3. 我们再次在最后一个R代码块中使用context: server来表示它包含Shiny服务器代码。

页面布局

你创建的一些交互式文档将使用与Shiny组件交织的叙述,而有些(如本示例)将是全页面应用。有些甚至可能是混合的——例如,想象左侧的侧边栏包含控制输出与主文档正文中的叙述交织的输入。

请参阅关于组件布局的文章,以了解更多关于管理交互式文档布局的可用工具。

示例

以下是一些使用Shiny的Quarto文档的部署示例:

示例 来源 描述
老忠实 代码 演示如何将交互式图表融入文档的主要流程中。
K-均值 代码 演示使用更“应用式”的页面布局(侧边栏和主面板)
钻石 代码 演示另一种布局输入的方式(在页面底部分为三列)。

深入学习

要了解更多关于Shiny交互式文档的信息,请参阅以下文章:

  • 运行文档 涵盖了如何在RStudio内和命令行中运行交互式文档,以及如何将它们部署给最终用户。

  • 执行上下文 深入探讨了不同代码块(例如渲染与服务)何时运行,以及如何缓存昂贵的计算以获得更灵敏的文档。

  • 外部资源 描述了如何确保Shiny能够找到您在文档中包含的资源(例如CSS、JS、图像等)。

  • 组件布局 列举了在文档中布局交互式组件的各种技术。

如果你同时使用JavaScript和Shiny来创建交互式文档,你可能还会对使用Shiny Reactives与OJS的文章感兴趣。