Jimmy那些事儿

R_文档输出_rmarkdown

rmarkdown & knitr

R Markdown文件

借助于R扩展包knitr的帮助, 可以把Markdown格式的源文件中插入R代码, 使得R代码的结果能够自动插入到最后生成的研究报告中。 这种格式称为R Markdown格式, 相应的源文件扩展名为.Rmd。 还有一个R扩展包rmarkdown也可以用来把R Markdown格式的文件转换为各种报告格式, 如HTML、docx、pdf、beamer等。

knitr的详细文档参见网站knitr文档

RStudio是一个集成的R软件环境, 可以用来编辑和执行R程序, 这个软件也可以用来编辑和编译R Markdown格式的文件, 使得R Markdown格式的文件变得容易使用。 在RStudio中可以直接用一个快捷图标一次性地把R代码结果插入内容中并编译为HTML或MS Word docx格式, 还支持Markdown中LaTeX格式的数学公式。 建议使用RStudio软件作为R Markdown文件的编辑器。

输出文档

在RStudio软件中,用菜单“File–New File–R Markdown”新建一个R Markdown文件,扩展名为.Rmd

如果不借助于RStudio软件, 可以用R软件、knitr包、rmarkdown包、pandoc软件来完成R Markdown源文件的编译。

比如,假设test.Rmd是一个这样的R Markdown格式的文件, 在不使用RStudio软件时, 可以在R中运行如下命令以生成含有运行结果的html文件:

1
2
3
library(knitr); library(markdown)
knit('test.Rmd', encoding='UTF-8')
markdownToHTML(file='test.md', output='test.html', encoding='UTF-8')

其中调用knit()函数会把.Rmd文件转换为.md文件, 调用markdownToHTML()函数会把.md函数转化为.html文件, 产生的HTML文件带有图形、支持数学公式。

在R中可以用如下命令把.md文件转化为MS Word docx格式:

1
system('pandoc -o test.docx test.md')

这里用system()命令从R内部调用了Pandoc.exe可执行程序。 需要把Pandoc.exe的位置加入的操作系统的Path环境变量中。


1
2
3
4
5
6
7
---
title: ''
output:
word_document: default
pdf_document: default
html_document: default
---


文本样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
链接:
图片: ![Title](URL) :本地或网络链接均可
网址: http://example.com
[RMarkdown初试](http://example.com)
加粗:**Bold**或--Bold--
斜体字:*Italics*或--Italics--
删除线:~~text~~
段落: 段落之间空一行
换行符: 一行结束时输入两个以上空格
列表:
无序列表:
* Item 1
* Item 2
+ Item 2a
+ Item 2b
有序列表:
1. Item 1
2. Item 2
3. Item 3
+ Item 3a
+ Item 3b
引用:> 引用内容
画水平线或分页:三个'-'以上,如:---
上标:a^2^
下标:a~1~


公式

1
2
##行内公式: $公式$
##行间公式: $$公式$$


在R Markdown文件中插入R代码

插入的R代码分为行内代码代码块

  • 行内代码的结果插入到一个段落中间, 代码以`r开头,以` 结尾, 如sin(pi/2)在结果中会显示为1。
  • 代码块则把结果当作单独的段落, 按照Markdown格式的规定, 代码块的前后需要有空行, 但是R Markdown实际上放松了这个要求, 允许前后不空行。 R代码段以单独的一行开头, 此行以三个反单撇号开始, 然后是{r}。 代码段以占据单独一行的三个反单撇号结尾。 如
1
2
3
4
​```{r}
1:5
sum(1:5)
1
2
3
4
5
结果将变成
```r
1:5
1
## [1] 1 2 3 4 5
1
sum(1:5)
1
## [1] 15

可以看出,代码段程序会被插入到最终结果中, 代码段的文本型输出会插入到程序的后面

代码块也可以嵌入到引用、列表等环境中。

代码块中作的图将自动插入到当前位置。 下面的程序:

1
2
3
4
​```{r}
plot(1:10)
hist(rnorm(1000))
1
2
3
4
5
结果将显示为:
```r
plot(1:10)

img

1
hist(rnorm(1000))

img

为了将这样的R代码段包括首尾标志原样显示, 需要将代码段整体地缩进4个空格, 并在开始的三个反单撇号前面加上r‘’``, 即生成一个空字符串的行内R代码, 原来的三个反单撇号的标志变成了

1
r`''`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
在RStudio中, 可以用**Insert快捷图标**插入代码段, 还可以用**Ctrl+Alt+I快捷键插入代码段**。
<br>
## 输出表格
knitr包提供了一个 `kable()` 函数可以用来把数据框或矩阵转化成有格式的表格, 支持HTML、docx、LaTeX等格式。
- **knitr::kable(x, format)**:
>format = c("latex", "html", "markdown", "pandoc", "rst") ;一般会自动进行调整
>
>digits = 最大的有效位数(对于数字列);也可以用一个向量,长度为`ncol(x)` 为单独的列设置有效位数
>
>> digits=2 (同一设置有效位数为2)
>>
>> digits=c(1,1,1,2,2) ;表示共有5列,为每一列指定
>
>row.names = T/F
>
>col.names =c(""); 一个字符串向量用来指定列
>
>align = c("") ;对齐方式;默认时文字左对齐,数字右对齐;若align=NULL,则按照默认来对齐;
>
>> l = left ; r = right ; c = center;
>>
>> **当 lenght(align)==1L,字符串会被解释为每个列设置方式的向量; 例如 "clc" 会被解释为c(‘c', 'l', 'c')**
>
>caption ="" ;标题
>
>format.args =list() 一个列表list形式的参数传递给format函数
>
>> ```r
>> # format numbers using , as decimal point, and ' as thousands separator
>> x = as.data.frame(matrix(rnorm(60, 1e+06, 10000), 10))
>> kable(x, format.args = list(decimal.mark = ",", big.mark = "'"))
>> [1] "| V1| V2| V3| V4| V5| V6|"
>> [2] "|-----------:|-----------:|-----------:|-----------:|-----------:|-----------:|"
>> [3] "| 997'476,8| 995'812,9| 994'992,8| 1'000'122,4| 981'053,9| 988'843,5|"
>>

>

format函数

trim = F/ T; 若为FALSE,进行右对齐;

digits= NULL;表示有效位数

justify = c(“left”, “right”, “center”, “none”)

width= NULL

na.encode = TRUE

scientific = NA ;科学计数法

big.mark = “”千分位分隔符

big.interval= 3L

small.mark=”” ;小数中的分隔符

small.interval=5L

decimal.mark=”” ;小数与整数的分隔符

zero.print=NULL

1
2
3
>> kable(c(1.23241415), format.args = list(small.mark = ","))
>> | 1.23241,4|
>>

>

longtable = T/F

例如,计算线性回归后, summary()函数的输出中有coefficients一项,是一个矩阵, 如果直接文本显示比较难看:

1
2
3
x <- 1:10; y <- x^2; lmr <- lm(y ~ x)
co <- summary(lmr)$coefficients
print(co)
1
2
3
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -22 5.5497748 -3.964125 4.152962e-03
## x 11 0.8944272 12.298374 1.777539e-06

可以用knitr包的kable函数来显示:

1
knitr::kable(co)
Estimate Std. Error t value Pr(>\ t\ )
(Intercept) -22 5.5497748 -3.964125 0.0041530
x 11 0.8944272 12.298374 0.0000018


R扩展包xtable提供了一个xtable()函数, 也可以用来生成HTML格式和LaTeX格式的表格, 但是需要指定要输出的格式。 xtable对比较多的R数据类型和输出类型提供了表格式显示功能, 包括矩阵、数据框、回归分析结果、方差分析结果、主成分分析结果、 若干分析结果的summary结果等。 例如,上面的回归结果用xtable()函数显示如:

1
print(xtable::xtable(lmr), type='html')
Estimate Std. Error t value Pr(>\ t\ )
(Intercept) -22.0000 5.5498 -3.96 0.0042
x 11.0000 0.8944 12.30 0.0000

这个代码段用了选项results='asis', 因为xtable生成的是直接用来插入到结果中的html代码。 注意这里指定了输出为HTML类型。 如果将本文件转化为docx, xtable的结果不可用。


格式转换

其他方式: scales包的函数:在传入kable之前进行修改

  • comma() :在千、百万、十亿等位置向数字添加逗号
  • dollar():添加一个美元符号并舍入到最近接的美分
  • percent():乘以100,舍入到最接近的整数值,并添加一个百分号
  • scientific():对大数字和小数字给出科学计数法都表示, 如3.30e+05
1
2
3
4
5
within(head(mtcars),{
wt <- round(wt, 2) # 小数为2位
percent() # 百分次
comma() # 千分位符
})


图形选项

fig.path: (‘figure/’; 字符):图片路径,支持前缀模式(‘figure/prefix-’)
fig.keep: (‘high’; 字符):保存图形类型,高级图形(‘high’)、不保存(‘none’)、所有图形(‘all’)、第一张(‘first’)、最后一张(‘last’)
fig.show: (‘asis’; 字符):展示方式,紧随代码输出(‘asis’)、最后统一输出(‘hold’)、动画输出(‘animate’)
dev: (LaTeX 为’pdf’, HTML/markdown 为’png’; 字符):输出设备,knitr 支持很多种设备
fig.width, fig.height: (7; 数值):图片文件的宽、高(英寸2.54cm 为单位)
out.width, out.height: (NULL; 字符):图片在输出文档中的宽、高
fig.align: (‘default’; 字符):对齐方式,不做调节(‘default’)、左(‘left’)、右(‘right’)、居中(‘center’)
interval: (1; 数值):动画参数,切换画面时间,单位为秒

图形大小 - fig.width/height

  • fig.width=指定生成的图形的宽度, 用fig.height=指定生成的图形的高度, 单位是英寸(1英寸等于2.54厘米)。
  • 两者默认为7 (英寸)

fig.width =10 ;刚好扩展到全部宽度

可在最初的knitr::opts_chunk$set(echo = FALSE, fig.width = 10) 中设置

下面给出一个长宽都是10厘米的图例。

1
2
3
4
​```{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)
1
2
3
4
5
6
结果为:
```r
curve(exp(-0.1*x)*sin(x), 0, 4*pi)
abline(h=0, lty=3)

img

fig.width=fig.height=规定的是生成的图形大小, 实际生成图形的显示大小会受到dpi(分辨率)影响, 默认dpi是72(每英寸72个点), 也可以用dpi=选择分辨率。 转化后的HTML文件显示时不一定按原始大小显示。 用out.width=out.height=可以指定显示大小, 但是可以是最终文件格式承认的单位, 比如HTML的图形大小单位是点(平常说屏幕分辨率的单位)。 例如在上面的例子中加上输出长宽都是600点的选项:

1
2
3
4
​```{r fig.width=10/2.54, fig.height=10/2.54, out.width=600, out.height=600}
curve(exp(-0.1*x)*sin(x), 0, 4*pi)
abline(h=0, lty=3)
1
2
3
4
5
6
注意所有选项都要写在一行中,不能换行。 结果为:
```r
curve(exp(-0.1*x)*sin(x), 0, 4*pi)
abline(h=0, lty=3)

img

在knitr的LaTeX版本(扩展名为.Rnw)中, 连续两个图形如果指定的宽度加起来比行宽窄会自动并排显示, R的bookdown扩展包提供了R Markdown格式的扩展, 其中的图形可以变成浮动图, 而且很容易并列放置。

图形结果选择

fig.keep=选项可以选择保留哪些R代码生成的图。 缺省是fig.keep='high', 即保留每个高级图形函数的结果图形, 低级图形函数对高级图形函数的更改不单独保存而汇总到高级图形函数结果中。 如

1
2
3
par(mar = c(3, 3, 0.1, 0.1))
plot(1:10, ann = FALSE, las = 1)
text(5, 9, "Testing low level graphics")

img

其中text()函数的结果与高级图形函数plot()的结果一起显示。

fig.keep还可以取:all, 会把低级图形函数修改后的结果单独保存; last, 仅保留最后一个图形;first, 仅保留第一个图; none, 所有图都不显示出来。


代码段选项

独立代码段以三个反向单撇号和{r}开头, 在大括号内还可以写一些选项, 选项与开始的r用空格分隔, 选项之间用逗号分隔, 所有选项写在同一行内。 选项都使用“选项名=选项值”的格式, 选项值除了使用常量外也可以使用全局变量名或表达式。 在大括号内除了开头的 r 写一个不是选项名的名字, 就作为代码段的标签。 如

1
2
3
4
5
6
7
8
​```{r firstCode}
cat('This is 第一段, 有标签.\n')
​```
# 只显示结果,不显示代码
​```{r echo=FALSE}
1:5
1
2
3
4
5
6
<br>
### 代码和文本输出结果格式
R代码块和R代码块的运行结果通常是代码块原样输出, 运行结果用井号保护起来, 这样有利于从文章中复制粘贴代码。 如:

1
2
3
4
s <- 0
for(x in 1:5) s <- s + x^x
s

1
2
结果为:

s <- 0
for(x in 1:5) s <- s + x^x
s

1
2

[1] 3413

1
2
3
4
5
6
7
8
9
10
11
12
13
#### highlight选项
转化后的R代码块缺省显示为彩色加亮形式。 用选项`highlight=FALSE`关闭彩色加亮功能。
#### prompt和comment选项
如果希望代码用R的大于号**提示符开始**, 用选项`prompt=TRUE`。 如果希望结果不用井号保护, 使用选项`comment=''`。 例如:
```r
​```{r prompt=TRUE, comment=''}
sum(1:5)
1
2
3
4
5
结果为:
```r
> sum(1:5)
1
[1] 15

echo选项 - 代码显示

echo = TRUE - 同时显示代码块 + 结果

echo = FALSE - 不显示代码块,但显示结果

如果希望不显示代码, 加选项。 如

1
2
3
​```{r echo=FALSE}
print(1:5)
1
2
3
4
5
结果为:
```r
## [1] 1 2 3 4 5

eval - 仅显示

加选项eval=FALSE, 可以使得代码仅显示而不实际运行。 这样的代码段如果有名字, 可以在后续代码段中被引用。

include - 仅运行

加选项include=FALSE, 则本代码段仅运行, 但是代码和结果都不写入到生成的文档中。


tidy选项

加选项tidy=TRUE可以自动重新排列代码段, 使得代码段格式更符合规范。例如:

1
2
3
4
​```{r tidy=TRUE}
s <- 0
for(x in 1:5) {s <- s + x^x; print(s)}
1
2
3
4
5
6
7
8
9
结果为:
```r
s <- 0
for (x in 1:5) {
s <- s + x^x
print(s)
}
1
2
3
4
5
## [1] 1
## [1] 5
## [1] 32
## [1] 288
## [1] 3413

child选项

加选项child='文件名.Rmd'可以调入另一个.Rmd文件的内容。 如果有多个.Rmd文件依赖于相同的代码,可以用这样的方法。

collapse选项 - 文本块输出

一个代码块的代码、输出通常被分解为多个原样文本块中, 如果一个代码块希望所有的代码、输出都写到同一个原样文本块中, 加选项collapse=TRUE。 例如, 没有这个选项时:

1
2
3
4
​```{r}
sin(pi/2)
cos(pi/2)
1
2
3
4
5
结果为:
```r
sin(pi/2)
1
## [1] 1
1
cos(pi/2)
1
## [1] 6.123032e-17

代码和结果被分成了4个原样文本块。 加上collapse=TRUE后,结果为:

1
2
3
4
sin(pi/2)
## [1] 1
cos(pi/2)
## [1] 6.123032e-17

代码和结果都在一个原样文本块中。

results选项 - 文本结果类型

用选项results=选择文本型结果的类型。 取值有:

  • markup, 这是缺省选项, 会把文本型结果变成HTML的原样文本格式。
  • hide, 运行了代码后不显示运行结果。
  • hold, 一个代码块所有的代码都显示完, 才显示所有的结果。
  • asis, 文本型输出直接进入到HTML文件中, 这需要R代码直接生成HTML标签, knitr包的kable()函数可以把数据框转换为HTML代码的表格。

例如:results='hold'的示例:

1
2
3
4
​```{r collapse=TRUE, results='hold'}
sin(pi/2)
cos(pi/2)
1
2
3
4
5
6
7
8
结果为:
```r
sin(pi/2)
cos(pi/2)
## [1] 1
## [1] 6.123032e-17



缓存(cache)选项

当R Markdown文章比较长,包含的R代码比较多, 或者代码段运行需要比较长时间时, 反复编译整篇文章会造成不必要的计算, 因为有些代码段并没有修改, 依赖的数据也没有改变。 knitr提供了缓存功能, 代码段选项cache=TRUE对代码段打开缓存, 允许暂存上次运行的结果(包括文本结果和图形) 而不需要重复运行代码段。 当代码段被修改时, 缓存被放弃, 编译时重新运行代码段。

缓存这种功能需要慎重使用, 免得错误地使用了旧的结果。 当后面的代码段需要使用前面代码段结果时, 如果前面结果改了, 后面的代码段就不能使用缓存的结果而必须重新计算。 为此, 在后面的代码段中应该加上dependson=选项, 比如dependson=c('codeA', 'codeB'), 其中codeAcodeB是前面的代码段的标签, 其结果会用在本代码段中。 也可以使用代码段选项autodep=TRUE, knitr试图自动确定前后代码段之间的依赖关系, 每当前面的代码段改变时, 后面的用到其结果代码段也自动重新计算而不使用缓存的旧结果。

建议仅对计算一次需要较长时间的代码段使用缓存功能, 后面依赖于其结果的代码一定要加上dependson=选项。


输出格式设置

在R Markdown格式的文件开头, 可以有用两个仅由三个减号组成的行包围的元数据段, 其中使用YAML格式, 使用冒号表示属性名与属性值, 用缩进表示属性值。

属性中, output选择输出的格式, 如html_document是HTML输出, pdf_document是PDF输出, word_document是docx格式的Word文件输出, 等等。 在每种输出格式后面还可以继续添加该输出特有属性。 如:

1
2
3
4
5
output:
html_document:
toc: yes
word_document:
toc: yes

上例中,output属性的值是两项, 两项用缩进表示; html_document又有自己的属性toc, 属性值yes表示要自动生成可点击的目录。 设置某种输出格式的属性nuber_sectionsyes可以自动对章节编号。

章节目录链接

对于英文文件, R Markdown基于的pandoc软件可以自动从标题生成适当的链接标签, 对于中文文件的支持差一些, 所以中文文件要自动生成可点击的目录, 需要在每个标题行的末尾,空格后添加{ #label}, 其中label是自己指定的标签内容, 但是建议仅使用英文字母、数字、减号。 如

1
### 第三章第一节标题 {#c3-s1-int}