第 5 章 R Markdown

5.1 R Markdown 可以做什么?

比较常用的格式有:

  • 单篇文档
    • R 数据分析笔记本(html_notebook
    • HTML文档(html_document
    • PDF文档(pdf_document
    • word文档(word_document
    • 仪表盘(flexdashboard::flex_dashboard
  • 书(bookdown框架)
    • HTML版本
      • gitbook
      • ctexbook
      • html_book
    • pdf版本(pdf_book
    • epub版本(epub_book
    • 格式和书一样丰富的单篇文档
      • HTML文档(html_document2
      • PDF文档(pdf_document2
      • word文档(word_document2
  • 网站(bolgdown框架)
    • HTML版本

注意,在HTML、仪表盘中,都支持Shiny和交互式图(基于Widgets框架)。

5.2 为什么用R_Markdown

使用R Markdown的初衷在于,用它能方便地进行数据探索与分析。它能将R代码与文档有机地结合在一起,类似于Python用户常用的jupyter笔记本。这里所用的输出格式为html_notebook

当数据探索与分析完成后,我们也经常需要交付数据分析报告。和word、PPT等传统报告相比,用R Markdown 做的可重复性分析报告(Reproducible reports)将更有优势。可重复性分析报告是这样一种形式:它将说明文字、数据、代码、计算结果、可视化图表等结合在一起,其中的计算结果与可视化图表由对应的代码自动生成,而不是先在其他环境中运行代码、保存结果、再将结果复制粘贴到报告中。可重复性分析报告相比于传统的分析报告,至少包含3点优势:

  • 代码与说明文字有机结合,使得代码更加易读,而说明文字更有说服力。它与在程序中直接写注释的区别在于,文字是富文本格式,可以有非常美观的排版,且还可以包含图表及更丰富的展示形式(如互动式图表、仪表盘等,可参看https://rmarkdown.rstudio.com/gallery.html)。
  • 结果是直接通过代码生成的,因而任何数据、方法的改动会直接导致结果的变化,而无需担心忘记更新结果。
  • 任何阅读报告的人,可通过报告中的代码,复现报告中的结果,因而报告是可重复,因而是可信的。只要数据源不作假,在整个分析过程与结果中,没有任何造假的空间。想通过PS对结果图进行修改,或者伪造、篡改中间数据来造假都是不可能的。

此时,用 R Markdown 输出 html_documentpdf_documentword_document是一个好的选择,具体选择有赖于项目要求。

5.3 文档总体设置

Rmd文件可以渲染为不同的文档,这在文件开头的YAML块中进行设置。YAML块是Rmd文件最上方进行全局设置的代码块,上下被3个减号包围,它不是Markdown语法,而是YAML语法。下面是一个典型的块:

---
title: "标题"
author:
  - 郭晓
date: "2019-01-01"

# 以html或word格式输出
output: 
  html_document:
    theme: cerulean
    toc: true
    # toc_depth: 2
    toc_float:
      true
    number_sections: true
  # word_document

---

title、author、date按字面意思填写。output为输出文档的格式,常见的格式在本章开头已经给出。以#开头的为注释。下一级设置比上一级注释缩进2个空格。theme为主题设置。toc为目录。更多设置可参考谢益辉的R Markdown: The Definitive Guide

5.4 富文本格式

5.4.1 普通文本

直接输入文本即可。当文本中含中文时,输出HTML时一般没有问题,但输出PDF时,一般需要有特别的设置,方便起见,可以在已有的中文报告模板的基础上,进行修改。

为了避免代码的歧义性,建议每个元素块代码与其他元素块代码之间都用空行分隔。比如正文与标题之间、正文与代码块之间等。

5.4.2 分段

仅仅在代码中换行,输出既不会分段,也不会换行。要想分段,需要在两段的代码之间空一行。输出结果会显示合适的段间距,但不会输出一个空行。

5.4.3 Markdown的换行

如果仅仅想显示换行,而不分段,则在上一行代码中结尾添加两个空格。
换行与分段的差异在于,分段的段间距一般会比行间距大很多。注意这一行与上一行之间的间距,和这一行与下一段的间距的差异。

这是下一段的示例,用于显示段间距。

5.4.4 各级标题

最常用方法是,n级标题前加n个井号#,标题与井号之间用空格分隔。如1级标题的代码# 一级标题。我自己一般最多仅能忍受4级标题,再往下会用数字列表或无序列表。

1级、2级标题有替代的格式:

  • 1级标题前不加#,而是在紧接的下一行用任意个等号=分隔,该行不能有其他符号,如

    1级标题的另一种表达方式
    ===================================
    任意正文
  • 2级标题前不加#,而是在紧接的下一行用任意个减号-分隔,该行不能有其他符号,如

    2级标题的另一种表达方式
    ------------------------------------
    任意正文

使用该方法的场合是:当需要用分隔线将代码分隔,以使得代码结构更加清晰时,该方法是一个可考虑的方法,比如该方法在dashboard中比较常见。

如果全局设置标题为编号的方式,而需要某个标题不编号,则在标题后添加{-}{.unnumbered}即可。

5.4.5 分隔线

单行3个及以上的减号-,该行没有其他符号,且与上下文本之间有空行分隔,则显示为分隔线。如

上一部分文本

------------------------------------

下一部分文本

分隔线与2级标题的区别在于,分隔线的连续减号必须与上面的文本之间有空行,而2级标题的连续减号必须紧接着上一行标题。

5.4.6 RMarkdown 的注释

  • 文本注释:依然可使用Ctrl+Shift+C的快捷键,其结果为在待注释的文本前添加<!--,在其后添加-->
  • R代码注释:无论是行内代码还是代码块,对于代码正文(不包括前后的斜引号及大括号里面的内容)来说,依然可使用Ctrl+Shift+C的快捷键,其结果与普通R脚本中的注释相同,为在待注释的文本前加井号#,文本注释与R代码注释举例如下:

    这是行内R代码注释`r # notes`

    这是未被注释的Markdown文本
    <!-- 这是文本注释 -->
    ```{r}
    # 这是R代码中的文本注释,和R脚本中的文本注释相同
    # a <- "this is the notes of code"
    b <- "this is normal code"  # notes
    ```

5.4.7 无序列表

  • 在每一条前面添加减号-或加号+或乘号*,并用空格将该符号与文本分隔,则显示为无序列表。
  • 列表的各条之间如果有空行,间距视为段间距,如果没有空行,间距视为行间距。
  • 三种符号之间可以任意混用。对显示效果没有影响。但建议同一级列表采用同一种符号开头。建议多级列表依次采用减号-、加号+与乘号*开头,超过3级循环使用。
  • 次级列表比上级列表至少多空2个空格或1个Tab键,建议采用空一个Tab的形式。
    • 这是次级列表。
  • 多段列表:

    后面的段落与第一段列表开头对齐,且与前一段之间有空行。

  • 列表中含代码块,列表终止,见pandoc文档 https://pandoc.org/MANUAL.html#pandocs-markdown

5.4.8 有序列表

  1. 在每一条前面添加一个数字与点,并用空格将该符号与文本分隔,则显示为数字有序列表。
  2. 数字可以是任意非负整数,可以是多位数,且不必按顺序写,可用重复数字,显示的序号从第1条的数字开始编号。
  3. 替代方案有
    1. 用英文圆括号将数字括起来开头,项目符号和文本之间用空格分隔。
    2. 数字后面接一个后圆括号,项目符号和文本之间用空格分隔。
    3. 以上两种方式,显示的效果依然为数字加点的形式。
  4. 次级数字列表比上级列表至少多空3个空格或2个Tab键,也即项目符号至少和上一级的正文对齐,建议用3个空格的形式。
  1. 在每一条前面添加一个小写字母与点,并用至少1个空格将该符号与文本分隔,则显示为小写字母有序列表,显示的序号从第1条的字母开始编号。
  2. 在每一条前面添加一个大写字母与点,并用至少2个空格将该符号与文本分隔,则显示为大写字母有序列表,显示的序号从第1条的字母开始编号。
  3. 项目符号不能是字母组合,且不必按顺序写。
  1. 在每一条前面添加一个小写罗马数字与点,并用至少1个空格将该符号与文本分隔,则显示为小写罗马数字有序列表,显示的序号从第1条的数字开始编号。
  2. 在每一条前面添加一个大写罗马数字与点,并用至少2个空格将该符号与文本分隔,则显示为大写罗马数字有序列表,显示的序号从第1条的罗马数字开始编号。
  3. 如果小写罗马数字项目符号i.接在同一级的小写字母项目符号之后,则会识别为小写字母项目符号。
  4. 如果大写罗马数字项目符号I.接在同一级的大写字母项目符号之后,则会识别为大写字母项目符号。
  5. 以上两种情况,可以通过插入列表截止符号来解决,任意文本注释,如<!-- 列表切割线 -->都可以作为列表截止符号。
  1. 也可以用井号#代替以上的阿拉伯数字、罗马数字与字母,作为偷懒形式,则符号会显示为该小节中上方最近的列表形式。如果上方没有列表,则默认为数字列表。
  2. 如果作为数字与小写字母的偷懒形式,项目符号与文本之间至少空1格,如果作为大写字母的偷懒形式,项目符号与文本之间至少空2格,与上面相应的形式一致。
  3. 字母、罗马数字、以及井号,同样可用左右圆括号包围、只用右括号分隔来代替用点分隔的形式。
  4. 改变了项目符号的形式,则序号会重新开始编号。
  5. 多级有序列表,建议采用数字、小写字母、大写字母、小写罗马数字、大写罗马数字的顺序。

5.4.9 复杂列表

无序列表、有序列表、代码块、引用块等形式可以混合。一般采用下一级的项目符号与上一级的正文对齐原则即可。

对多段列表来说,后面的段落与第一段列表开头对齐,且与前一段之间有空行。若后面的段落为代码块等块状内容,与多段列表相同。对代码块来说,是一个道理。以下是一些示例,需要查看原markdown代码才可以很好理解下面的例子。

  • ```markdown
    这个代码块包含了代码块的符号
    ```
    下一段文字示例
  • 这个列表将代码放在中间

    这里只有代码块的文本
  • 这里也只有代码块的文本

5.4.10 斜体

  • 一般情况:用1个星号*括起来就可以了,如代码*斜体*的效果为斜体
  • 也可以用下划线_代替星号,如代码_斜体_的效果也为 斜体,但此时前下划线必须与前面的文本之间用空格分隔。
  • 当待加粗的文本本身含有*时:在文本的星号前加上反斜杠即可,代码*\*带有星号的文本*显示为 *带有星号的文本

5.4.11 加粗

  • 一般情况:用2个星号*括起来就可以了,如代码**加粗**的效果为加粗
  • 也可以用下划线_代替星号,如代码__加粗__的效果也为 加粗,但此时前下划线必须与前面的文本之间用空格分隔。

5.4.12 粗斜体

  • 一般情况:用3个星号*括起来就可以了,如代码***粗斜体***的效果为粗斜体
  • 也可以用下划线_代替星号,如代码___粗斜体___的效果也为 粗斜体,但此时前下划线必须与前面的文本之间用空格分隔。

5.4.13 行内代码文本

一般情况下,用斜引号(重音符)`括起来就可以了,如代码`a <- 1`的效果为a <- 1

若代码中要显示斜引号本身,则需要用更多的斜引号括起来,最多含有n不连续的斜引号要用n+1斜引号括起来,n+1对斜引号与文本中间用空格分隔。如为了显示```code``` ,我们的代码应该为```` ```code``` ```` ;为了显示`隔断``中间文本``隔断`,我们的代码应该为``` `隔断``中间文本``隔断` ```

如果文本中没有斜引号,用多个斜引号括起来也可以,只要前后个数相同,且都在一行之内,效果与前后用一个斜引号相同。

当代码文本以小写字母r开头,且之后接着空格和其他文本,比如想输出r 开头的代码格式文本时,直接写`r 开头的代码格式文本`,系统会将其识别为r代码,将开头的代码格式文本识别为一个找不到的r对象,最终报错,因而要做特殊的处理。这里的思路是,首先必须将其看作一段r代码,但这段r代码的输出可以是我们需要的文本,即`r 'r 开头的待输出文本'`,注意在r代码中,字符串用引号括起来,而不是斜引号。但此时输出的格式为纯文本格式,而非代码格式。和前面的思路一样,我们需要用斜引号将其括起来。然而,直接用斜引号括起来会报错,因而我们将斜引号换成它的16进制写法\x60,代码变成了`r '\x60r 开头的代码格式文本\x60'`。现在该文本显示为了代码的形式,显示结果为r 开头的代码格式文本

如果我们要输出的代码文本是在上面的基础上,在外面再加上斜引号,即想输出类似于下面的代码文本:`r 开头的代码格式文本`问题会更加复杂。首先,文本中含有斜引号,则需要在外面用2个斜引号括起来;其次,斜引号之后,是以r空格开头的文本,这需要将该文本作为r代码,且代码中的斜引号用它的十六进制符号\x60代替。综合起来,代码应该写成这样子:`r '\x60\x60 \x60r 开头的代码格式文本\x60 \x60\x60'`。文本中包含更多的斜引号以此类推,文本中包含引号或反斜杠时,在其前面加上反斜杠作为非转义字符。

中文bookdown输出pdf时,行内代码没有灰色背景,不知道如何解决。

5.4.14 代码文本块

  • 一般情况下,在代码块的前一行与后一行用三个斜引号括起来即可,例如下面的代码

    ```
    b <- "this is normal code"
    ```

    其输出为

    b <- "this is normal code"

    为了让代码输出更美观,可以利用代码高亮功能。即在开头的三个斜引号之后,标注该代码的语言,如

    ```r
    b <- "this is normal code"
    ```

    其输出为

    b <- "this is normal code"

    注意不要用括号将r括起来,否则会被视为可执行的r代码。

  • 当要显示的代码文本块是如下的R代码块的markdown形式时,情况会复杂些。因为,即使被斜引号括起来,该代码块还是会被视为可执行的R代码块。

    ```{r}
    b <- "this is normal code"  # notes
    ```

    我们解决的思路与输出行内r代码的markdown形式相同,即将需要输出的本文作为r代码的字符串输出,将斜引号用其十六进制符号\x60代替。为了显示以上代码,我们需要写的代码是

    ````markdown
    `r '\x60\x60\x60{r}
    b <- "this is normal code"  # notes
    \x60\x60\x60'`
    ````

    含有更复杂的斜引号情况以及其他转义字符的情况,以此类推。

  • 除了用三个斜引号括起来的方式,还有其他可替代的显示代码文本的方式
    • 在代码块每一行前添加4个空格或2个tab,如(用空格的劣势在于失去了代码高亮的功能。)

          b <- "this is normal code" # 注意代码前有4个空格
    • 在代码块前一行前添加至少3个波浪号,在代码块后一行添加至少和代码前相同多的波浪号,如

      ~~~r
      b <- "this is normal code"
      ~~~

    都与以下代码的效果相同

    ```r
    b <- "this is normal code"
    ```

5.4.15 下标

文本前后用一对插入符号^包围,则该文本显示为下标。如x~1~显示为x1

5.4.16 上标

文本前后用一对波浪号~包围,则该文本显示为上标。如x^2^显示为x2

5.4.17 同时上下标

目前只知道依次上下标的形式,如x~1~^2^显示为x12,如果需要同时上下标,可以直接用公式。

5.4.18 行内公式

用一对美元符号$包围LaTeX公式,如$f(x)=\sqrt{x}$显示为\(f(x)=\sqrt{x}\)。公式在R studio 浏览器中无法正常显示,但在R studio代码窗口或系统浏览器中是正常的。

5.4.19 公式块

用2对美元符号$$包围LaTeX公式,如$$f(x)=\sqrt{x}$$显示为 \[f(x)=\sqrt{x}\]

5.4.20 特殊字符与转义符

转义符为反斜杠\,当符号具有特殊功能时,要想输出符号本身,在前面加转义符。

单独的大括号可以正常输出,如{},或左括号{,右括号}.

5.4.21 链接

  • 对与文本就是网址的情况来说,无需特殊格式,输入该超链接的文本,系统会自动识别其为超链接。注意该文本应与周围文本用空格分隔。
  • 对文本不同于网址的情况来说,格式为[显示文本](网址),如下面代码[RStudio](https://www.rstudio.com),其效果为RStudio

5.4.22 插入图片

格式为![图片说明](图/片/路/径),注意图片路径中为正斜杠而不是反斜杠,包含文件名本身。如果图片所在位置就在项目所在文件夹,在文件名前加点与斜杠,如![图片说明示例](./fig.png)显示为

图片说明示例

图片说明示例

如果图片的代码与上下文之间不空行,图片显示的格式如同引用块,单独在下一行。图片后面的文字也会另起一行,但不显示图片说明。如果图片的代码与上下文之间都空行,则会显示图片说明。图片说明在图片下方左侧显示,灰色字体区别于正文的黑色。

当路径中含中文时,在Rstudio浏览器中无法正常显示;当路径不含中文,文件名为中文时,无法在R脚本窗口显示。所以建议路径和文件名都用英文。

如果想控制图片的显示尺寸,可以用下面的方式:

```{r echo=FALSE, fig.cap="插入本地图片", out.width = '30%'}
knitr::include_graphics("./fig.png")
```

显示为:

插入本地图片

图 5.1: 插入本地图片

在上面的方法中,将路径名改为网址,还可以插入来自网络的图片(以及本地或网络的gif动图),如

```{r echo=FALSE, fig.cap="来自网络的图片", out.width = '30%'}
knitr::include_graphics("https://d33wubrfki0l68.cloudfront.net/aee91187a9c6811a802ddc524c3271302893a149/a7003/images/bandthree2.png")
```

显示为:

来自网络的图片

图 5.2: 来自网络的图片

5.4.23 插入表格

显示表格的代码的形式有多种,但是显示出来的表格本身的风格只有一种。

以下代码

  Right     Left     Center     Default
-------     ------ ----------   -------
     12     12        12            12
    123     123       123          123
      1     1          1             1
      
Table:  Demonstration of simple table syntax.

显示为

Demonstration of simple table syntax.
Right Left Center Default
12 12 12 12
123 123 123 123
1 1 1 1

以下代码

-------------------------------------------------------------
 Centered   Default           Right Left
  Header    Aligned         Aligned Aligned
----------- ------- --------------- -------------------------
   First    row                12.0 Example of a row that
                                    spans multiple lines.

  Second    row                 5.0 Here's another one. Note
                                    the blank line between
                                    rows.
-------------------------------------------------------------

Table: Here's the caption. It, too, may span
multiple lines.

显示为

Here’s the caption. It, too, may span multiple lines.
Centered Header Default Aligned Right Aligned Left Aligned
First row 12.0 Example of a row that spans multiple lines.
Second row 5.0 Here’s another one. Note the blank line between rows.

以下代码

: Sample grid table.

+---------------+---------------+--------------------+
| Fruit         | Price         | Advantages         |
+===============+===============+====================+
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
+---------------+---------------+--------------------+
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |
+---------------+---------------+--------------------+

显示为

Sample grid table.
Fruit Price Advantages
Bananas $1.34
  • built-in wrapper
  • bright color
Oranges $2.10
  • cures scurvy
  • tasty

以下代码

| Right | Left | Default | Center |
|------:|:-----|---------|:------:|
|   12  |  12  |    12   |    12  |
|  123  |  123 |   123   |   123  |
|    1  |    1 |     1   |     1  |

  : Demonstration of pipe table syntax.

显示为

Demonstration of pipe table syntax.
Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

对格式的要求包括:

  • 表的代码结尾必须空行。或者添加虚线后再空行,虚线可以连续,也可以间断。表头上方可以有一行减号,也可以没有。
  • 如果每行内容都是单行,则表主体部分各行之间无需符号分隔,表头与主体之间用减号分隔。
  • 如果需要表内包含多行内容,则结尾必须添加虚线后再空行,虚线可以连续,也可以间断。表头上方必须有一行减号。处于表格不同行的内容,用空行分隔。处于表格同一行,但文本上不同行的内容,分行,但是不用空行分隔。
  • 表头可以省略,但是表头与表主体之间的分隔符不能省略。当表头省略时,结尾必须添加虚线后再空行,虚线可以连续,也可以间断。
  • 表格中显示的内容可以左对齐、右对齐、或居中对齐,规则如下
    • 若表头与主体之间的分隔线(以下简称分隔线),左端与表头对齐,右端超出表头,则该列左对齐;
    • 若分隔线右端与表头对齐,左端超出表头,则该列右对齐;
    • 若分隔线左右端都超出表头,则该列居中对齐;
    • 若分隔线左右端都与表头对齐,则选择默认格式,一般还是左对齐;
    • 当表头被省略时,用分隔符与表格第一行对齐的形式代替上述的分隔符与表头对齐的形式。
    • 如果采用全围栏式,在分隔符中加入冒号,冒号在左端为左对齐,在右端为右对齐,两端都有显示为居中对齐,下面是一个例子。

      以下代码:

      +--------------:+:--------------+:------------------:+
      | Right         | Left          | Centered           |
      +---------------+---------------+--------------------+

      显示为

      Right Left Centered

表标题:在表格代码上方或下方以Table::开头的文字视为表标题。没有单独的表说明。

5.4.24 引用块

在每一段文本(包括空行)前加入>与空格,如以下代码:

> "I thoroughly disapprove of duels. If a man should challenge me,
I would take him kindly and forgivingly by the hand and lead him
to a quiet place and kill him."
>
> --- Mark Twain

显示为

“I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him.”

— Mark Twain

5.4.25 对勾框

可以用LaTeX语法产生对勾框与对勾,如 - 对勾框:代码$\Box$显示为\(\Box\) - 对勾:代码$\checkmark$显示为\(\checkmark\)

5.4.26 字体

用HTML语法实现,如<span style="font-family:楷体;">楷体</span>显示为楷体<span style="font-family:Times New Roman;">Times New Roman</span>显示为Times New Roman

5.4.27 字号

用HTML语法实现,如<span style="font-size:5px;">字号25px</span>显示为字号25px

5.4.28 文字颜色

用HTML语法实现,如<span style="color:red;">红色文字</span>显示为红色文字<span style="color:#33C0FF;">文字色号#33C0FF</span>显示为文字色号#33C0FF

5.4.29 背景颜色

用HTML语法实现,如<span style="background-color:yellow;">背景为黄色</span>显示为背景为黄色<span style="background-color:#33FF8B;">背景色号为#33FF8B</span>显示为背景色号为#33FF8B

5.4.30 划线

用HTML语法实现,如<p style="text-decoration: underline;">下划线</p>显示为

下划线

<p style="text-decoration: line-through;">删除线</p>显示为

删除线

<p style="text-decoration: overline;">上划线</p>显示为

上划线

5.4.31 对齐

默认为左对齐。可用HTML语法实现其他对齐。

<p style="text-align:center;">
这是居中对齐的段落。
</p>

显示为:

这是居中对齐的段落。

<p style="text-align:right;">
这是右对齐的段落。
</p>

显示为:

这是右对齐的段落。

<p style="text-align:justify;">
这是分散对齐的段落,文字不到一行。
</p>

显示为:

这是分散对齐的段落,文字不到一行。

<p style="text-align:justify;">
这是分散对齐的段落,文字超过一行。由于网址较长,它被分在了第2行,https://bookdown.org/connect/#/apps/2540/access 。这样,第1行文字就不足一行了,,它会分散对齐而非左对齐显示。读者可对比这一段和左对齐段落的区别。
</p>

显示为:

这是分散对齐的段落,文字超过一行。由于网址较长,它被分在了第2行,https://bookdown.org/connect/#/apps/2540/access 。这样,第1行文字就不足一行了,,它会分散对齐而非左对齐显示。读者可对比这一段和左对齐段落的区别。

<p style="text-align:justify;text-justify:distribute-all-lines;text-align-last:justify;">
这是单行强制分散对齐。
</p>

显示为:

这是单行强制分散对齐。

5.4.32 缩进

用HTML语法实现:

<p style="text-indent:32px;">
首行缩进
</p>

首行缩进:这是超过一行的段落,第1行进行了缩进,接下所有行没有缩进。缩进的宽度是可以调节的。这里展示的常见的缩进两个汉字宽度的形式,可以设置为2em32px

<p style="text-indent:-5em;padding-left:5em;">
悬挂缩进
</p>

悬挂缩进:这是超过一行的段落,第1行未进行缩进,接下来所有行都进行了缩进。缩进的宽度是可以调节的。这里展示的缩进5个汉字宽度的形式。

<p style="padding-left:2em;">
整体左缩进
</p>

整体左缩进:这是超过一行的段落,所有行左侧都进行了缩进。缩进的宽度是可以调节的。这里展示的缩进2个汉字宽度的形式。

<p style="padding-left:2em;padding-right:2em">
整体左右均缩进
</p>

整体左右均缩进:这是超过一行的段落,所有行左、右侧都进行了缩进。缩进的宽度是可以调节的。这里展示的缩进2个汉字宽度的形式。

5.4.33 插入视频

用HTML语法实现:

<video controls>
  <source src="video-example.mp4" type="video/mp4">
</video>

<span style="font-size:12px;"> *来自本地的视频。*</span>

效果为:

来自本地的视频。

<video controls>
  <source src="https://www.w3schools.com/html/movie.mp4" type="video/mp4">
</video>

<span style="font-size:12px;"> *来自网络的视频,网址为:https://www.w3schools.com/html/movie.mp4 *</span>

来自网络的视频,网址为:https://www.w3schools.com/html/movie.mp4

5.4.34 插入音频

用HTML语法实现:

<audio controls>
  <source src="audio-example.mp3" type="audio/mp3">
</audio>

效果为

5.4.35 添加附件

用HTML语法实现:

<a href="data.csv" download="data.csv">点击下载附件 *data.csv*</a>

效果为

点击下载附件 data.csv

5.5 与代码的交互

5.5.1 行内代码

用斜引号括起来,然后内部加上r和空格,后面写r代码,如`r Sys.time()`显示为2019-05-26 12:27:31

行内R代码只显示代码的结果,不显示代码本身。

5.5.2 代码块

在Rstudio中用快捷键Ctrl+Alt+I可快速添加R代码块,其格式为在代码前一行添加```{r},在代码后一行添加```,如以下代码

```{r}
x <- 1
y <- 2
z <- x + y
z
```

显示为

x <- 1
y <- 2
z <- x + y
z
## [1] 3

一般情况下,R代码会显示出来,作为一个块,R代码会被执行,结果会在下方的另一个块中显示出来,如果是数值或文本,前面会以两个井号开头。如果有警告或报错,也会显示出来。如果想调节这些的显示方式,以及做更多的设置,设置的代码(称之为代码块选项)写在```{r}之间,各选项用逗号分隔。以下会说明具体的可设置的功能与设置方式,更多选项见 https://yihui.name/knitr/options

5.6 代码块选项

5.6.1 是否执行

代码块选项设置eval=FALSE,则该代码块不执行,但仍会显示。

5.6.2 是否显示代码

代码块选项设置echo=FALSE,则该代码块不显示,但仍会执行,会显示结果与报错等。

5.6.3 是否展示结果

代码块选项设置results='hide',则该代码块执行且显示,但结果不显示,但是警告等依然会显示。

5.6.4 展示原本结果格式

代码块选项设置results='asis',结果显示为原本的样子,如前方没有两个井号,没有灰色作为背景等。还可以让输出的文本具有markdown格式,如代码

```{r}
cat('**Markdown** is cool.\n')
```

显示为

cat('**Markdown** is cool.\n')
## **Markdown** is cool.

而代码

```{r,results='asis'}
cat('**Markdown** is cool.\n')
```

显示为

cat('**Markdown** is cool.\n')

Markdown is cool.

注意在第二次的输出结果中,文本Markdown被加粗,且没有井号作为前缀,没有灰色背景。

5.6.5 代码与结果放在一起

代码块选项设置collapse = TRUE,则代码与结果放在一个灰色背景中,中间没有空行。

5.6.6 是否展示警告与错误

  • 代码块选项设置warning = FALSE,则不显示警告;
  • 代码块选项设置error = FALSE,则不显示报错;
  • 代码块选项设置message = FALSE,则不显示通知信息。

5.6.7 仅执行

代码块选项设置include = FALSE,则仅执行代码,不显示代码,不显示结果,不显示警告、报错等等。它等价于echo=FALSE, results = 'hide', warning = FALSE, message = FALSE

5.6.8 全局代码块设置

如果想让所有代码块都执行相同的设置,则可在文档第1个代码块仿照下面的方式进行设置:

```{r, setup, include=FALSE}
knitr::opts_chunk$set(fig.width = 8, collapse = TRUE)
```

5.6.9 图片格式设置

用out.width(out.height)设置图片相对宽度(高度),参数为百分数形成的字符串。也可直接设置图片长宽的绝对值,如fig.width=6, fig.height=6,单位为英寸。fig.align设置图片对齐,可以是’center’、’left’、’right’。fig.cap设置图标题。如果想让多幅图并列显示,则可设置fig.show='hold',然后调节图片宽度。

例如下面的代码

```{r,fig.show='hold' ,out.width='40%', fig.align='center', fig.cap='自定义图片格式'}
plot(1:5)
plot(6:10)
```

显示为:

自定义图片格式自定义图片格式

图 5.3: 自定义图片格式

5.6.10 表格格式设置

如果是普通的data.frame格式,一般用knitr::kable函数展示。align参数设置对齐,“l”为左对齐,“c”为居中,“r”为右对齐。也可以用长度等于列数的向量来设置每一列的对齐方式。digits参数控制小数点位数,相当于给每一个数值传入round函数。caption给出表标题。下面为一个例子。

library(knitr)
kable(head(iris), align="c")
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa

如果是tibble格式,在某些格式设置(如html_document中)下可直接输出(但在gitbook中效果不好)

library(tidyverse)
as_tibble(head(iris))
## # A tibble: 6 x 5
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
## 1          5.1         3.5          1.4         0.2 setosa 
## 2          4.9         3            1.4         0.2 setosa 
## 3          4.7         3.2          1.3         0.2 setosa 
## 4          4.6         3.1          1.5         0.2 setosa 
## 5          5           3.6          1.4         0.2 setosa 
## 6          5.4         3.9          1.7         0.4 setosa

5.7 交互式图表

5.7.1 交互式数据表

在下面的交互式数据表中,你可以改变每页显示的行数,可以按某一列进行排序,可以在多页之间进行跳转,可以搜索表格中你想要的数据。

library(DT)
datatable(iris, options = list(pageLength = 5))

5.7.2 交互式数据图

5.7.2.1 例1

在下面的交互式数据图中,你可以通过鼠标拖动,改变数据的显示范围。

library(dygraphs)
dygraph(nhtemp, main = "New Haven Temperatures") %>% 
  dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))

5.7.2.2 例2

在下面的交互式数据图中,你可以通过鼠标画框的方式,改变数据的显示范围。可以通过鼠标停靠,得到图中的数据具体值。

library(plotly)
p <- ggplot(data = diamonds, aes(x = cut, fill = clarity)) +
  geom_bar(position = "dodge")
ggplotly(p)

5.7.2.3 例3

在下面的交互式数据图中,你可以拖拽网络图中节点的位置,可以通过鼠标滚轮放大和缩小视图。

library(visNetwork)
nodes <- data.frame(id = 1:6, title = paste("node", 1:6), 
                    shape = c("dot", "square"),
                    size = 10:15, color = c("blue", "red"))
edges <- data.frame(from = 1:5, to = c(5, 4, 6, 3, 3))
visNetwork(nodes, edges) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)

5.7.2.4 例4

在下面的交互式数据图中,你可以通过鼠标画框的方式,改变数据的显示范围。可以通过鼠标停靠,得到图中的数据具体值。

library(d3heatmap)
d3heatmap(mtcars, scale="column", colors="Blues")

5.7.2.5 例5

在下面的交互式数据图中,你可以通过鼠标拖动,从不同视角查看这个3维立体图。

library(threejs)
z <- seq(-10, 10, 0.1)
x <- cos(z)
y <- sin(z)
scatterplot3js(x, y, z, color=rainbow(length(z)))

5.7.2.6 例6

在下面的交互式数据图中,你可以与动态地图交互。

library(leaflet)
m <- leaflet() %>%
  addTiles() %>%  # Add default OpenStreetMap map tiles
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
m

5.7.3 动态数据图

5.7.3.1 例1

将一系列数据图转化为gif,可以增加对数据的洞察,下面例子来自 https://blogdown-demo.rbind.io/2018/01/31/gif-animations/ 。注意需要提前安装 FFmpeg 软件,安装方法见 https://zh.wikihow.com/%E5%9C%A8Windows%E4%B8%8A%E5%AE%89%E8%A3%85FFmpeg%E7%A8%8B%E5%BA%8F

```{r fig.show='animate', dev='jpeg', ffmpeg.format='gif'}
for (i in 1:10) plot(runif(100), ylim = c(0, 1)) # for example
```

5.7.3.2 例2

下面的效果和最近一篇比较火的可视化文章 Who runs China? 类似。

library(datasauRus)
library(ggplot2)
library(gganimate)

ggplot(datasaurus_dozen, aes(x=x, y=y))+
  geom_point()+
  theme_minimal() +
  transition_states(dataset, 3, 1) + 
  ease_aes('cubic-in-out')
## 
Frame 1 (1%)
Frame 2 (2%)
Frame 3 (3%)
Frame 4 (4%)
Frame 5 (5%)
Frame 6 (6%)
Frame 7 (7%)
Frame 8 (8%)
Frame 9 (9%)
Frame 10 (10%)
Frame 11 (11%)
Frame 12 (12%)
Frame 13 (13%)
Frame 14 (14%)
Frame 15 (15%)
Frame 16 (16%)
Frame 17 (17%)
Frame 18 (18%)
Frame 19 (19%)
Frame 20 (20%)
Frame 21 (21%)
Frame 22 (22%)
Frame 23 (23%)
Frame 24 (24%)
Frame 25 (25%)
Frame 26 (26%)
Frame 27 (27%)
Frame 28 (28%)
Frame 29 (29%)
Frame 30 (30%)
Frame 31 (31%)
Frame 32 (32%)
Frame 33 (33%)
Frame 34 (34%)
Frame 35 (35%)
Frame 36 (36%)
Frame 37 (37%)
Frame 38 (38%)
Frame 39 (39%)
Frame 40 (40%)
Frame 41 (41%)
Frame 42 (42%)
Frame 43 (43%)
Frame 44 (44%)
Frame 45 (45%)
Frame 46 (46%)
Frame 47 (47%)
Frame 48 (48%)
Frame 49 (49%)
Frame 50 (50%)
Frame 51 (51%)
Frame 52 (52%)
Frame 53 (53%)
Frame 54 (54%)
Frame 55 (55%)
Frame 56 (56%)
Frame 57 (57%)
Frame 58 (58%)
Frame 59 (59%)
Frame 60 (60%)
Frame 61 (61%)
Frame 62 (62%)
Frame 63 (63%)
Frame 64 (64%)
Frame 65 (65%)
Frame 66 (66%)
Frame 67 (67%)
Frame 68 (68%)
Frame 69 (69%)
Frame 70 (70%)
Frame 71 (71%)
Frame 72 (72%)
Frame 73 (73%)
Frame 74 (74%)
Frame 75 (75%)
Frame 76 (76%)
Frame 77 (77%)
Frame 78 (78%)
Frame 79 (79%)
Frame 80 (80%)
Frame 81 (81%)
Frame 82 (82%)
Frame 83 (83%)
Frame 84 (84%)
Frame 85 (85%)
Frame 86 (86%)
Frame 87 (87%)
Frame 88 (88%)
Frame 89 (89%)
Frame 90 (90%)
Frame 91 (91%)
Frame 92 (92%)
Frame 93 (93%)
Frame 94 (94%)
Frame 95 (95%)
Frame 96 (96%)
Frame 97 (97%)
Frame 98 (98%)
Frame 99 (99%)
Frame 100 (100%)
## Finalizing encoding... done!