R语言教程:RMarkdown
本文默认读者已经安装好 R language 和 Rstudio
一、前置知识
我们之前付费文章或者R语言教程用到的RMarkdown文件很多同学想了解怎么用。它跟python语言下的jupter notebook一样,可让我们边写笔记边运行代码并且展示代码结果,最后还能把写好的文件转换成报告,而且它更简单易用
MIMIC数据库R语言实战:预测 30 天内的再入院率(一)
文献分享和R语言复现:评估 MIMIC-IV v2.2 和 MIMIC-IV-ED 数据集中的不同诊断
MIMIC-IV数据分析 - 使用R语言进行患者信息的跟踪追溯
MIMIC-IV数据分析 - 使用R语言探索icustay_detail视图
双击打开RStudio
File - New file - RMarkdown
即可新建文件
新建的一般是未命名文件
二、RMarkdown简介
R Markdown文档中的文本是用Markdown语法编写的。确切地说,这是Pandoc的
Markdownhttps://pandoc.org/MANUAL.html。
三、RMarkdown安装
你需要有R和RStudio。接下来需要安装rmarkdown包:
方式1:
# 从CRAN安装稳定版
install.packages('rmarkdown')
方式2:Tools - Install Packages - 写入 rmarkdown - install
如果想生成PDF格式的输出文件,需要安装LaTex。如果你没有安装过的话,可以安装TinyTeX。
install.packages('tinytex')
tinytex::install_tinytex() # 安装TinyTeX
有了rmarkdown包、RStudio/Pandoc和LaTeX,就能够编译大多数R Markdown文档。在某些情况下,可能需要其他R包,我们将在用到时候再细说。
四、RMarkdown基础
下面是一个最基础的R Markdown文档,它本身是一个纯文本文件,后缀名为.Rmd
:
---
title: "R Notebook"
author: "白鲸鱼"
output: html_notebook
col: "科研收录"
---
This is a paragraph in an R Markdown document.
Below is a code chunk:
```{r}
fit = lm(dist ~ speed, data = cars)
b = coef(fit)
plot(cars)
abline(fit)
```
The slope of the regression is `r b[1]`.
如果你使用RStudio,你可以从菜单栏File -> New File -> R Markdown
,创建RMarkdown文档。
R Markdown文档有三个基本组件:元数据metadata、文本text和代码code。元数据写在这对三个破折号之间---
。元数据的语法是YAML (YAML不是标记语言),因此有时它也被称为YAML元数据或YAML frontmatter。预先警告您缩进在YAML中很重要,所以不要忘记正确地缩进顶部字段top field的子字段sub-field。请参阅Xie(2016)的 附录B.2,以获得一些显示YAML语法的简单示例。文档的主体在元数据之后。文本(也称为prose或narratives)的语法是Markdown。有两种类型的计算机代码:
-
代码块以三个反引号开始,比如
```{r}
,其中r
表示语言名称,以三个反引号结束。你可以在花括号中写入chunk选项(例如,设置图形高度为5英寸:```{r, fig.height=5}
。 -
行内R代码表达式以
`r
开头,以 反引号`
结尾。
然后可以单击Knit
按钮来编译文档(到HTML页面),页面默认输出在RStudio的Viewer窗口。
五、编写R Markdown文档
编译R Markdown文档的通常方法是点击Knit
按钮,相应的键盘快捷键是Ctrl + Shift + K
(在macOS上是Cmd + Shift + K
)。在底层,RStudio在新的R会话中调用函数rmarkdown::render()
渲染文档。
请注意,在新的R会话中渲染Rmd文档意味着当前R会话中的对象(例如,在R控制台中创建的对象)都不会被渲染。可重现性是RStudio使用一个新的R会话来呈现Rmd文档的主要原因:文档在下次打开R或在其他人的计算环境中继续工作。
如果你必须在当前的R会话中呈现一个文档,你也可以自己调用rmarkdown::render()
,并将Rmd文件的路径传递给这个函数。这个函数的第二个参数是输出格式,默认为您在YAML元数据中指定的第一个输出格式(如果缺少该格式,则默认为html_document
)。当你在元数据中有多种输出格式,并且不想使用第一种格式时,你可以在第二个参数中指定你想要的格式,例如,对于Rmd文档foo.Rmd
与元数据:
output:
html_document:
toc: true
pdf_document:
keep_tex: true
可以通过一下命令渲染成PDF:
编写Rmd文档的另一种主要方式是R Markdown Notebooks。暂不介绍。
最后,我想提到一种“非官方”的编译Rmd文档的方法:xaringan::inf_mr()
函数,或者类似的,RStudio addin插件“Infinite Moon Reader”。显然,这需要您安装xaringan包(Xie 2021e)。这种方式的主要优势是liverload:一种技术使您可以在保存源文档时实时预览输出,而不需要点击Knit按钮。另一个特点是,它在当前R会话中编译Rmd文档,这可能是您所希望的,也可能不是。请注意,此方法只适用于输出到HTML的Rmd文档,包括HTML文档和演示文稿。
一些R Markdown扩展包,如bookdown和blogdown,有自己的编译文档的方式,我们将在后面介绍它们。
注意,也可以从一个R Markdown源文档呈现一系列报告,而不是单个报告。您可以参数化R Markdown文档,并使用不同的参数生成不同的报告。
rmarkdown::render('foo.Rmd', 'pdf_document')
六、备忘清单(Cheat sheet)
RStudio创建了大量的备清单(cheat sheet),包括一页的R Markdown备忘单,可以在上免费获得。https://www.rstudio.com/resources/cheatsheets/
七、R代码块和R行内代码
可以使用RStudio工具栏(Insert
按钮)或快捷键Ctrl + Alt + I
(Cmd + Option + I
)插入R代码块。
在代码块中可以做很多事情:可以生成文本输出、表格或图形。你可以通过块选项很好地控制所有这些输出,这些选项可以在大括号中设置(在```{r
和 }
之间)。例如,你可以通过chunk选项results = 'hide'
选择隐藏文本输出,或者通过fig.height = 4
. 设置图形高度为4英寸。Chunk选项用逗号分隔,例如:
```{r, chunk-label, results='hide', fig.height=4}
在谢益辉的blog中https://yihui.name/knitr/options有大量的chunk选项。下面我们列出了其中的一个子集:
除了代码块标签(chunk label)不需要tag
,仅需要输入value
。其他选项都是通过键值对的形式输入tag=value
。当然,代码块标签选项也可以显性采用键值对的形式输入label='自定义标签名'
。每个代码块的标签是唯一的,如果没有手动指定其标签值,RMarkdown会自动命名为unnamed-chunk-i
,i是增量的正数。
7.3.5.1 全局设置
如果某个选项需要在多个代码块中频繁地设置为一个值,你可以考虑在文档的第一个代码块(YAML的下方)中全局设置它,你可以使用knitr::opts_chunk$set()
来改变文档中chunk选项的默认值。例如,你可以把它放在你文档的第一个代码块:
例子一:
```{r, setup, include=FALSE}
knitr::opts_chunk$set(fig.width = 8, collapse = TRUE)
```
例子二:
```{r, setup, include=FALSE}
knitr::opts_chunk$set(
comment = '', fig.width = 6, fig.height = 6
)
```
7.3.5.2 代码执行(Code evaluation)
-
eval
:(TRUE
;逻辑值或数字) 。是否运行代码块。它也可以是一个数值向量来选择要执行的R代码,例如,eval = c(1,3,4)
将执行第一个、第三个和第四个R代码,而eval = -(4:5)
将求值除第四个和第五个代码之外的所有代码。
7.3.5.3 文本输出(Text output)
-
echo
:(TRUE
;逻辑值或数字)是否在输出文档中显示源代码。除了显示/隐藏源代码的TRUE/FALSE
之外,我们还可以使用一个数值向量来选择在一个代码块中要显示的R代码,例如,echo = 2:3
表示只显示第2和第3个代码,echo = -4
表示排除第4个代码。 -
results
:(`makeup`
;字符)控制如何显示文本结果。注意,此选项仅适用于普通文本输出(对warnings、messages和errors不起作用)。取值如下: -
markup
:默认的显示形式,可不写,本书返回的结果基本都是此默认值。 -
asis
:文本输出为本身as-is
,在文档中直接输出其结果 -
hold
:一个代码块所有的代码都显示完, 才显示所有的结果。 -
hide
:运行了代码后不显示运行结果。 -
collapse
:(FALSE
;逻辑值),是否将一个代码块中的源代码和输出写在同一个块(默认情况下,它们被写入不同的块) -
warning
:(TRUE
;逻辑值) ,是否在输出中保留警告。如果为FALSE
,所有警告将在控制台中显示,而不是文档中显示。还可以输入数字,例如,3表示从这个代码块中显示第三个警告。 -
error
:(FALSE
;逻辑值),默认代码发生错误error时会停止。如果想出现错误的情况下,后续代码继续允许的话,需要改为TRUE
。如果希望得到错误警告并继续允许后续代码,则可以设置error = 0
。 -
message
: (TRUE
; 逻辑值) 是否保留message()发出的消息 -
include
: (TRUE; 逻辑值) 如果,变为FALSE
则本代码段仅运行, 但是代码和结果都不写入到生成的文档中。 -
strip.white
: (TRUE; 逻辑值) 是否删除输出中源代码块开头或结尾的空行 -
class.output
: (NULL; 字符)添加到文本输出块中的类名向量。此选项仅适用于R Markdown中的HTML输出格式。例如,class.output = c('foo', 'bar')
,文本输出将被放置在<pre class="foo bar"></pre>
。
7.3.5.4 代码装饰(Code decoration)
-
tidy
: (FALSE)
是否自动重新排列代码段, 使得代码段格式更符合规范。 -
TRUE
: 调用formatR::tidy_source()
函数自动重新排列代码段。 -
prompt
: (FALSE
; logical) -
TRUE
代码用R的大于号提示符开始 -
comment
: (‘##’; character) -
TRUE
希望结果不用井号保护 -
highlight
: (TRUE
; logical) 是否以语法高亮显示源代码。
7.3.5.5 缓存(Cache)
-
cache
: (FALSE
; logical) 为了保险起见, 可以尽量不使用缓存功能, 而是用save()功能将需要长时间结算的结果保存下来, 用load()载入然后输出到结果文档中。
7.3.5.6 图片(Plots)
-
fig.width
andfig.height
: 指定生成的图形的宽度和高度, 单位是英寸(1英寸等于2.54厘米)。如果同时指定,也可以使用fig.dim = c(6, 4)
等价于fig.width = 6
且fig.height = 4
。
下面给出一个长宽都是10厘米的图例。
```{r fig.width=10/2.54, fig.height=10/2.54}
curve(exp(-0.1*x)*sin(x), 0, 4*pi)
abline(h=0, lty=3)
```
curve(exp(-0.1*x)*sin(x), 0, 4*pi)
abline(h=0, lty=3)
-
out.width
和out.height
控制输出文档中R图片的输出大小,即缩放图像。应百分比,例如out.width = '80%'
表示图片为页面宽度的80%。 -
fig.align
:图片的对齐方式. 取值可为'left'
,'center'
, 或'right'
。 -
dev
:记录R图的图形设备(graphical device)。通常情况下,LaTeX输出是'pdf'
, HTML输出是'png'
,但你当然可以使用其他设备,如'svg'
或'jpeg'
。
如果编译输出目标是HTML, 程序产生的图形是PNG格式, 属于点阵图, 图中的任何中文内容不会有乱码问题。但是, 如果输出目标是PDF, 程序将产生PDF格式的图形, 这种图形属于矢量图, 需要正确设置文字编码才能保证图中的中文不会乱码。设置的办法是用pdf.options()函数作如下指定:
其中的family
选项指定了支持中文, 而height
和width
则是指定生成的每个图片的物理大小, 以英寸为单位。这样的设定一般都放在Rmd文件开头, YAML后面的位置, 用setup
作代码段标签, 加include=FALSE
代码段选项表示仅运行但不使用运行得到的文字和图形输出结果。
7.3.6 插入图片
默认情况下,由R代码生成的图形将立即放置在生成图形的代码块之后。例如
```{r}
plot(cars, pch = 18)
```
(1) 图片标题
您可以在chunk选项中使用fig.cap
选项设置图片标题。如果文档输出格式支持选项fig_caption: true
(输出格式rmarkdown::html_document
), R图形将被放置到图形环境中。在PDF输出的情况下,这些数字将被自动编号。
(2) 图片并排显示
要将多个图形从相同的代码块并排放置,你可以使用fig.show='hold'
选项和out.width
的选项。下图示例,有两个图,每个图的宽度为50%
。
```{r hold-position, fig.cap='Two plots side-by-side.', fig.show='hold', out.width='50%', fig.width=5, fig.height=4}
par(mar = c(4, 4, .2, .1))
plot(cars, pch = 19)
plot(pressure, pch = 17)
```
(3) 非R代码生成的图片
如果需要显示不是由R代码生成的图形,可以使用knitr::include_graphics()函数
,它比的Markdown语法更能控制图像的属性。
```{r, out.width='25%', fig.align='center', fig.cap='...'}
knitr::include_graphics('images/hex-rmarkdown.png')
```
7.3.7 表格
显示表格最简单方法是使用knitr::kable()
,它可以创建HTML, PDF和Word输出的表可以通过向设置caption
参数来包含表标题,例如:
```{r tables-mtcars}
knitr::kable(iris[1:5, ], caption = 'A caption')
```
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 |
如果您正在寻找表格样式化的更高级控制,建议您使用 kableExtra。
7.3.8 行内代码
除了代码块,你也可以在行内文本中插入R对象的值. 例如:
```{r}
x = 5 # 圆的半径
```
如果一个圆的半径为 `r x`,
它的面积等于 `r pi * x^2`。
显示为
x = 5 # 圆的半径
如果一个圆的半径为 5, 它的面积等于78.5398163。
7.3.9 在RMarkdown使用其他语言
关于R Markdown的一个鲜为人知的事实是,它还支持许多其他语言,如Python、Julia、c++和SQL。这种支持来自knitr包,它提供了大量的语言引擎,你可以通过以下方式列出所有可用引擎的名称:
names(knitr::knit_engines$get())
## [1] "awk" "bash" "coffee" "gawk" "groovy"
## [6] "haskell" "lein" "mysql" "node" "octave"
## [11] "perl" "php" "psql" "Rscript" "ruby"
## [16] "sas" "scala" "sed" "sh" "stata"
## [21] "zsh" "asis" "asy" "block" "block2"
## [26] "bslib" "c" "cat" "cc" "comment"
## [31] "css" "ditaa" "dot" "embed" "eviews"
## [36] "exec" "fortran" "fortran95" "go" "highlight"
## [41] "js" "julia" "python" "R" "Rcpp"
## [46] "sass" "scss" "sql" "stan" "targets"
## [51] "tikz" "verbatim" "theorem" "lemma" "corollary"
## [56] "proposition" "conjecture" "definition" "example" "exercise"
## [61] "hypothesis" "proof" "remark" "solution" "glue"
## [66] "glue_sql" "gluesql"
library(reticulate)
x = 'hello, python world!'
print(x.split(' '))
## ['hello,', 'python', 'world!']
后续待补充。