layout: post
title: "R制作研究报告"
date: 2019-11-29
tag: sas
20 用R制作研究报告
一个统计或数据分析的科研项目, 都会产生一个或多个研究报告。 因为使用统计与数据分析不可避免地有很多计算涉及在内, 这里假设使用R软件做了计算。 科研是一个不断改进的过程, 所以每一次重新做了计算, 研究报告中的汇总表格、图形都要更新。 这样的任务比较繁琐, 也容易出错。
"文学式编程"(literate programming, (Knuth 1984))是这样一种思想, 把撰写报告与计算程序有机地结合在一起, 用一个源文件文件既包含报告内容, 又包含计算程序。 每次产生研究报告时, 先运行源文件中的计算程序得到计算结果, 这些结果包括文字性内容与图形, 然后利用适当软件自动地把这些原始文字、计算结果组合成最终的报告。 利用这样的思想, 可以自动生成重复的例行报告, 还可以作为"可重复科学研究"的载体。
上述的源文件一般是文本文件, 格式可以是Markdown格式, 也可以是LaTeX格式等许多格式。 R的knitr软件包就是用来支持这样的编程思想的一个扩展包。
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名, 利用R程序进行扩展的版本保存为.Rmd扩展名。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。 Markdown仅适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过LaTeX编译器可以转换为PDF格式, 也可以将docx转存为PDF格式, 或者用输出到PDF文件的打印机将网页格式转换为PDF格式。
LaTeX是一个文档排版系统, 功能强大,结果美观, 设计合理。 缺点是需要学习类似于HTML的另一种语言。 LaTeX源文件主要是编译为PDF。
R扩展包knitr包支持在Markdown格式、LaTeX格式等类型的文件中插入R代码, 经过转换, 文中的R代码可以变成代码的结果文字、表格、图形, 与原有报告文字有机地结合在一起。
插入了R代码的markdowng格式的文件一般以.Rmd为扩展名, R的rmarkdown扩展包和knitr包一起为Rmd格式提供了支持。
R的bookdown包进一步增强了R Markdown格式的功能, 支持生成PDF、多文件互相链接的HTML、Word等输出, 其中的表格、图形可以变成浮动表, 公式、定理可以自动编号并支持文献、公式、定理、图表、章节的引用和链接, 所以比较适用于编写一本书或论文、研究报告。
knitr包也支持在LaTeX源文件中插入R代码, 通过编译使得R代码运行结果、图形自动插入生成的研究报告中。 原来有一个Sweave扩展包是支持在LaTeX中插入R代码的, 现在knitr的功能已经涵盖并增强了此包功能。
下面几章分别介绍markdown格式、R markdown格式、bookdown扩展包、简易网站制作和幻灯片制作。 参考:
(Xie, Allaire, and Grolemund 2019)
(Xie 2017)
利用R Markdown格式可以执行如下的任务:
将单一的R Markdown文件编译为不同的格式,如:
HTML;
PDF;
MS Word。
在RStudio软件内制作笔记本文档,可以在其中包含说明文字与R代码, 可以在笔记本文档内交互地运行R代码并能将结果交互地显示在笔记本内。
生成演示幻灯片,可以是基于HTML5的,也可以是基于LaTeX beamer扩展包的, 或者MS Powerpoint。
编写多章节组成的书籍。
编写期刊论文。
制作网站或者博客。
制作商业智能仪表盘(dashboards),即数据可视化展示。
References
Knuth, Donald E. 1984. "Literate Programming." The Computer Journal 27 (2): 97--111.
Xie, Yihui. 2017. Bookdown: Authoring Books and Technical Documents with R Markdown.
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
21 Markdown格式
21.1 介绍
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名。 Mardown中文内容应该使用UTF-8编码。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。
Markdown适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过docx格式可以转存为PDF格式。 R扩展包knitr、rmarkdown和bookdown与pandoc软件一起大大扩展了markdown格式的适用范围。
如果需要作为一本书发布在网站上或者出版, 可考虑使用R的bookdown扩展包。 如果需要对出版格式进行精确控制, 可考虑用LaTeX格式, LaTeX格式很复杂, 学习比较困难, 但是表达能力强。
21.2 Markdown格式文件的应用
Markdown格式用在一些微博、论坛中作为缺省格式, 用户在网络浏览器软件的输入框中按照markdown格式输入, 网站自动将其转换为html富文本内容显示出来。
因为markdown格式就是纯文本, 而且其格式十分简单, 所以可以仅仅用普通文本编辑器编写markdown格式的文件, 不需要转换为其它格式。
有一些独立运行的编辑软件, 在其中输入了markdown格式文件后, 可以并列地显示转化为html富文本后的结果, 很多还支持自动备份到云服务中。 但是,这些独立运行的编辑器大都有商业因素。 比如,国内的印象笔记软件是提供了云存储的笔记软件, 在其PC端就支持创建markdown格式的笔记, 可以在输入时即时显示html效果。
RStudio软件不是专用的Markdown编辑器, 它是一个R程序的集成编辑、运行环境, 对个人用户免费, 在R Studio中可以编辑Markdown文件和含有R代码的Markdown文件, 可以一键将其转化成HTML、MS Word docx文件, 在单独安装的LaTeX编译软件支持下还可以直接编译成PDF。 RStudio支持下的增强的Mardown格式, 称为RMarkdown格式, 以.Rmd为扩展名, 支持大多数的LaTeX公式, 在bookdown扩展包支持下还支持公式、定理、图表等自动编号和引用、链接。
21.3 markdown格式说明
这部分内容参考了markdown手册和Rstudio的文档, 以及(Xie, Allaire, and Grolemund 2019)。
21.3.1 概述
Markdown格式是John Gruber于2004年创造的, Markdown 的目标是实现"易读易写"。 Markdown定义了一种简单好用的文本文件格式, 作为单独的文本文件, 此格式没有什么多余的标签, 又可以转化为很多其它的格式。
Markdown 的语法全由一些符号所组成, 这些符号经过精挑细选,其作用一目了然。 比如:在文字两旁加上星号,看起来就像强调。 Markdown 的列表看起来就像我们平常在邮件中写一个列表的方法。 Markdown 的区块引用看起来就真的像是引用一段文字, 就像你曾在电子邮件中见过的那样。
需要时, 可以直接在markdown中写HTML标记内容。 markdown能实现的功能是HTML的一部分, 但是比HTML内容更干净, 没有掺杂过多的与要表达的意思无关的标签。 Markdown的理念是,能让文档更容易读、写和随意改。
21.3.2 段落
一个段落由一行或连续的多行组成。 段落之间以空行分隔。 同一段落内的不同行在转换成HTML或docx等格式后会重新排列, 原来的段内换行被当成了空格,这样的规定与LaTeX类似。 普通段落不该用空格或制表符来缩进, 不应在行尾留有空格。
为了在段内换行并且转化后仍保持段内换行, 输入时在前面行的末尾输入两个或两个以上空格。例如:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
显示结果为:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
这样做的缺点是末尾的空格时不可见的。 可以使用HTML的标签在段内换行,如:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
结果为
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
21.3.3 段内文字格式
在一段内,用星号或下划线包围的内容如强调 是强调格式。 用双星号或双下划线包围的内容如加重是加重格式。 星号、下划线与要强调或加重的内容之间不要空开, 否则会当作普通星号或下划线解释, 在行首还会当作列表。 为了插入普通的星号或下划线,可以使用反斜杠保护, 或者写成段内代码格式。
可以用一对~作为界定符给出下标, 如HO2会变成HO2。 可以用一对^作为界定符给出上标, 如Cu2+会变成Cu2+。 但是,数学公式一般还是应该使用LaTeX数学公式形式(见22.8)。
在普通段落内一部分内容希望显示成代码, 对其中的特殊字符不进行解释, 只要包在两个反向单撇号内。 如if(x > 0) y=1;会变成if(x > 0) y=1;。 如果内容本身就包含反向单撇号, 可以在两边使用更多个数的反向单撇号, 如x会变成x。
在Markdown文件中, 为了使得某些有特殊意义的字符不作特殊解释, 可以在该字符前面加上反斜杠\, 取消其特殊含义。
在Rmarkdown文件中, 为了原样显示反向单撇号, 可以在两边用双写的反向单撇号界定字符串。
21.3.4 标题和分隔线
以一个井号#开始的行是一级标题, 以两个井号#开始的行是二级标题, ............, 以六个井号#开始的行是六级标题。 标题行前面应该空一行, 否则可能把某些偶然出现在行首的#号误认为标题行的标志。
对一级标题, 也可以用标题内容下面输入一行等于号=表示上一行内容是一级标题。 对二级标题, 可以用标题内容下面输入一行减号-表示上一行内容是二级标题。 等于号和减号的个数不限。
用三个或三个以上连续的星号组成的行, 可以转换成分隔线。下面是一个分隔线:
21.3.5 引用段落
可以用类似Email的回复包含原始邮件内容的办法输入引用段落, 即,在段落的每行前面加一个大于号。 比如下面的诗:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
转换成
白日依山尽,黄河入海流。 欲穷千里目,更上一层楼。
注意引用也是段落模式,内容中的换行不起作用,空行导致分段。
引用段落也可以仅在段落第一行写大于号, 其它行顶格写,例如下面的两段引用:
远上寒山石径斜,
白云生处有人家。
停车坐爱枫林晚,
霜叶红于二月花。
转换成
远上寒山石径斜, 白云生处有人家。
停车坐爱枫林晚, 霜叶红于二月花。
引用也可以嵌套,如:
张三说:李四这样说过
不想当将军的木匠不是好厨子。
转换成
张三说:李四这样说过
不想当将军的木匠不是好厨子。
注意嵌套内容前后都有空的引用行,否则不能实现嵌套引用。
引用内也可以嵌套其它的Markdown格式如标题、列表等。 引用前后应该有空行把引用内容与其他内容分隔开。
21.3.6 列表
列表分为不编号的列表和编号的列表。 不编号的列表转化后通常显示圆点开头的列表项。
在Markdown中, 用星号表示一个不编号的列表项。 星号也可以替换成加号或减号, 后面必须有一个或多个空格。 每个列表项可以输入多行, 各行的内容最好左对齐, 左对齐在使用文本格式时较易阅读, 但不是必须的。 两个列表项之间不要空行。 例如:
- 白日依山尽,
黄河入海流。 - 欲穷千里目,
更上一层楼。
转换为
白日依山尽, 黄河入海流。
欲穷千里目, 更上一层楼。
段落顶头的数字加句点和空格表示编号列表, 两个列表项之间尽量不要空行。 例如:
- 第一种解决方法,
收买敌人的高官。 - 第二种解决方法,
尽可能拖延。
转换为
第一种解决方法, 收买敌人的高官。
第二种解决方法, 尽可能拖延。
标准的markdown编号列表不能自己定义数字的显示格式, 不允许开始值不等于1。 pandoc支持更自由的列表, 允许输入时有括号或右括号,允许使用字母和罗马数字,但是括号会被去掉。如
(1) 顶层一;
a) 内层二;
b) 内层三;
(2) 顶层二。
转换为
顶层一;
内层二;
内层三;
顶层二。
为了避免错误地产生非本意的编号列表, 在行首写数字加句点和空格时,可以在句点前加反斜杠, 或者在句点前加空格。例如,下面是一个年号:
如上输入将不会错误地解释为有序列表。
如果列表项目中有多个段落, 这时两个列表项之间应该以空行分隔, 每个项目除了第一行外,输入的每行内容都应该缩进4个空格或者一个制表符。 例如:
- R语言第一个版本开发于1976-1980,基于Fortran;
于1980年移植到Unix, 并对外发布源代码。
1984年出版的"棕皮书"
总结了1984年为止的版本, 并开始发布授权的源代码。
这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新,
变成了我们现在使用的S语言,称为第二版。
1988年出版的"蓝皮书"做了总结。 - 1992年出版的"白皮书"描述了在S语言中实现的统计建模功能,
增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。
现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
转换为
R语言第一个版本开发于1976-1980,基于Fortran; 于1980年移植到Unix, 并对外发布源代码。 1984年出版的"棕皮书" 总结了1984年为止的版本, 并开始发布授权的源代码。 这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新, 变成了我们现在使用的S语言,称为第二版。 1988年出版的"蓝皮书"做了总结。
1992年出版的"白皮书"描述了在S语言中实现的统计建模功能, 增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。 现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
列表项目内如果有引用段落, 需要都缩进4个空格。 如果有程序代码, 需要缩进4个空格后用三个反单撇号表示开始与结束。
列表可以嵌套, 嵌套的列表需要缩进4个空格, 中间不需要空行。 例如:
- 第一类工作包括:
- 技术服务;
- 咨询服务。
- 其它工作略。
转换为
第一类工作包括:
技术服务;
咨询服务。
其它工作略。
如果需要把每个列表项当作段落排版,可以在每个列表项后空行。
21.3.7 源程序
为了让源程序能够自动显示成源程序的样式, 而不至于自动分行、特殊字符解释, 用空行把源程序与其它内容隔开, 并把源程序行都缩进4个空格(或以上)或者一个制表符。 源程序格式持续到不缩进4个空格的地方为止。
例如,下面的输入:
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
转换为
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
更适当的做法是用三个连续的反向单撇号表示代码开头与代码结束, 中间就会当作源程序代码处理。 例如下面的输入
```
x <- rnorm(100)
hist(x)
```
转换为
x <- rnorm(100)hist(x)
R的knitr包在Markdown格式的文件中插入R可执行代码时, 就用了这样的方法。 而且,R Markdown格式的代码块不需要用空行与前后分隔开。
在pandoc程序的支持下, 代码段还可以采用栅栏式代码段, 在代码段开头前面一行加上至少三个连续~符号, 在结尾后面一行加同样数目的~符号。 这样的代码段前后也必须空行以与其它内容分开。 另外,如果代码内本身含有~行, 只要使得开头与结尾标志中的~个数更多就可以了。 例如下面的输入
#include <math.h>
double sqr(double x){
return(x*x);
}
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
使用栅栏式代码段时可以在开始行尾写大括号, 在大括号内写选项。 其中一种选项是要求按照某种编程语言对结果进行彩色语法显示, 如.cpp表示C++,.c表示C,.r表示R,.python表示python等。 选项.numberLines要求该代码行编号, 选项startFrom=指定开始行号。如 如:
{.cpp
#include <math.h>
double sqr(double x){
return(x*x);
}
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
21.3.8 链接
最简单的链接是原样显示的可点击的链接, 只要把链接地址用小于号和大于号包在中间, 两边用空格和其它内容隔开。 如果是网页,需要加http://, 如果是邮箱,需要加mailto:。 例如,如下代码:
北京大学的网页地址是: http://www.pku.edu.cn/ 。
显示为
北京大学的网页地址是: http://www.pku.edu.cn/ 。
除此之外, Markdown 还支持两种形式的链接语法: 行内式和引用式两种形式。 不管是哪一种,链接的显示文字都是用方括号[...]来标记。
要建立一个行内式的链接, 只要在方括号内写链接的显示文字, 右方括号后面紧接着圆括号, 并在圆括号中间插入网址链接即可。 方括号部分与圆括号部分之间不能断开。 例如:
请参考:李东风的教学主页
变成了
请参考:李东风的教学主页
在圆括号中,链接后面还可以包含用双撇号包围的标题文字, 与链接之间用空格分开。
引用式的链接, 需要在某处(比如文章结尾)定义一些链接的标识符, 然后用方括号包围链接的显示文字, 后面紧接着方括号包围着链接的标识符。
为了定义链接标识符, 用方括号包围链接标识符, 前面可以有至多3个空格缩进, 右方括号后面紧接着冒号和一个空格, 空格后写链接地址, 然后空格,在两个双撇号中间写一个链接地址的标题。 例如
这时,在文章中就可以用标识符调用链接, 如北京大学主页将变成链接北京大学主页。
使用引用式的链接, 有些像论文中把所有参考文献排列在文章末尾, 文中用到某一篇文献只要提及其序号。
还有一种链接是内部链接,用于文内跳转。 在各级标题行的末尾, 可以添加{#自定义标签}这样的内容, 其中"自定义标签"是自己写的一个标识符, 标识符仅使用英文字母、数字、下划线、减号, 用来区分不同的位置。 比如,本文第一节"介绍"添加了markdown-intro为标签, 就可以用"回到介绍"产生链接 回到介绍。
21.3.9 插入图形
图形只能用链接形式, 不可能保存到一个纯文本文件内。 图形文件可以存在于远程服务器上, 也可以是与生成的HTML文件在同一目录结构中的文件。 语法仍使用行内式和参考式两种形式。 转化成HTML、PDF、Word格式后可以把图形内嵌在输出文件内部。
行内式的图片链接, 是普通行内链接格式前面添加了一个叹号, 惊叹后面紧接着方括号, 方括号内写图片的标题,标题可以空缺, 在右方括号后面紧接着圆括号, 圆括号内写图片的链接。
例如,下面的代码可以插入百度的一个logo,使用的是网上的资源:

结果为
img
为了插入保存在本地的与Markdown源文件在同一子目录或下级子目录的图形, 只要在圆括号中写图片文件名(如果与Markdown源文件在同一子目录)或相对路径。 例如,在D:\work\figs下的图形文件baidu_logo.gif在本Markdown源文件所在目录的figs子目录中, 可以用代码

结果为
img
这样含有网上图片和本地图片的Markdown源文件转化为HTML和docx格式, 都可以正常显示插入的图片。
与链接类似, 也可以在文章某处(比如末尾)定义图片的标识符, 然后把行内图片引用中图片地址替换成图片标识符即可。
21.3.10 表格
Markdown文本格式的表格就像是用减号、等号、竖线画的文本格式表格一样, 转化为HTML、docx等格式后就变成了富文本的表格。 有如下几种表格:
管道表
简单表
换行表
有格表
21.3.10.1 管道表
管道表在两列之间用竖线分开, 在列标题下面用减号画横线, 用如下方法指定各对齐方式:
在列标题下的横线开始加冒号,表示左对齐;
在列标题下的横线末尾加冒号,表示右对齐;
在列标题下的横线两端加冒号,表示居中对齐;
列标题下面仅有横线没有冒号,表示缺省对齐方式,一般是左对齐。
在表格内容后面空一行后写用Table:开头的表格说明。
这种方法不需要输入内容上下对齐,适用于中文内容。 后面所讲的简单表、换行表、有格表需要能够输入内容对齐, 对于中英文混合内容很难做到对齐, 所以仅管道表比较适合中文内容。
例如:
| 姓名 | 收入 | 职业 | 颜色偏好 |
|---|---|---|---|
| 赵四海 | 123456 | 业务经理 | 红 |
| 刘英 | 50 | 无 | 蓝 |
| 钱德里 | 3200 | 保洁 | 灰 |
| Table: 管道表示例 | |||
| 结果为 |
姓名 收入 职业 颜色偏好
赵四海 123456 业务经理 红
刘英 50 无 蓝
钱德里 3200 保洁 灰
管道表不允许输入单元格换行, 单元格内容太宽时转换结果可能自动换行, 自动换行时列宽度与输入的列标题下横线宽度成比例。
21.3.10.2 简单表
简单表的格式是, 第一行是各列标题, 第二行是各标题下面用减号组成的表格线, 同一行的不同列要用空格分开, 从第三行开始是内容。
在表格前或表格后用空行隔开的以Table:开头的行是表格说明或标题。
为了确定表格每列单元格内容如何对齐, 用列标题下的表格线给出提示:
表格线与列标题右对齐,表示该列右对齐;
表格线与列标题左对齐,表示该列左对齐;
列标题在表格线中间,表示该列居中对齐;
列标题左右都与表格线对齐,表示该列为缺省对齐方式,一般是左对齐。
一定要使用一个等宽字体来编辑这样的表格,否则对齐与否无法准确分辨。 单元格内容不能超出表格线左端。 经过试验发现, 中文内容很难按这种方法对齐。
例如:
Name Income Job Color
Jane 123456 Research Assistant red
John 50 N/A blue
William 3200 Cleaner blue
Table: 一个简单表的例子
结果为:
Name Income Job Color
Jane 123456 Research Assistant red
John 50 N/A blue
William 3200 Cleaner blue
21.3.10.3 换行表
换行表在输入列标题和单元格内容时, 允许输入内容拆分行,但是转化后并不拆分行。 这样的表以一行减号开始,以一行减号结束, 中间的表格用空行分开实际的不同行。 例如:
Name
of
Subject Income Job color
Jane 123456 Research red
Ayer Assistant
John 50 N/A blue
Tukey
William 3200 Cleaner blue
Tale
Table: 一个换行表的例子
结果为:
Name of Subject Income Job color
Jane Ayer 123456 Research Assistant red
John Tukey 50 N/A blue
William Tale 3200 Cleaner blue
换行表输入时各列的输入宽度是有作用的, 输入较宽的列结果也较宽。
21.3.10.4 有格表
完全用减号、竖线、等于号、加号画出表格线。 这样的表在文本格式下呈现出很好的表格形状。 转化后不能指定对齐方式。
例如:
Table: 有格表示例
±--------------±--------------±-------------------+
| Fruit | Price | Advantages |
+=+=+====================+
| Bananas | $1.34 | - built-in wrapper |
| | | - bright color |
±--------------±--------------±-------------------+
| Oranges | $2.10 | - cures scurvy |
| | | - tasty |
±--------------±--------------±-------------------+
结果为
Fruit Price Advantages
Bananas $1.34 built-in wrapperbright color
Oranges $2.10 cures scurvytasty
21.4 附录:pandoc软件介绍
pandoc是一个杰出的开源软件, 作者为John MacFarlane。 RStudio软件中已经包含了这个软件。 软件在命令行运行, 可以用来在多种不同的文件格式之间进行转换, 输入格式一般是文本格式, 比如markdown、LaTeX、MediaWiki、reStructured Text、 HTML、DocBook, 但是也可以输入MS Word docx、Open Office ODT、EPUB格式。 输出可以是这些文本格式, 也可以是MS Word docx、Open Office ODT、EPUB、LaTeX等格式, 在安装了LaTeX编译系统如MikTeX时可以输出为PDF。 RStudio软件中包括了一份pandoc软件程序。
可以用普通文本编辑器编写markdown格式的文件, 用pandoc转换为HTML或MS Word docx等格式。 因为pandoc需要UTF8编码的输入文件, 所以应该把markdown文件保存为UTF格式, MS Windows下的Notepad++软件可以很容易地编辑文本文件 并在各种编码之间转换。 实际上,MS Windows下有一个markdown编辑程序Smarks就是基于pandoc软件的。
首先, 从pandoc网站下载并安装pandoc。 安装程序很奇怪地安装到了 C:\Users\登录用户名\AppData\Local\Pandoc中, 请将此子目录复制到一个合适的位置, 比如C:\Pandoc。 如果把此路径加入到Windows系统的可执行文件搜索路径中 (在"控制面板-系统和安全-系统-高级系统设置-环境变量"中, 为系统变量的Path添加一个分号分开的路径C:\Pandoc即可以不用全路径访问 pandoc.exe可执行文件。
为了用pandoc转化某个markdown文件, 首先在该文件所在子目录打开一个Windows命令行窗口, 在MS Win10系统中只要在文件管理器的"文件"菜单选择 "打开命令提示符"即可。 比如,文件名是test.md, 用如下pandoc命令可以转换为.docx文件(MS Word文件的新版本):
C:\Pandoc\pandoc -o test.docx test.md
用如下pandoc命令可以转换为.html文件:
C:\Pandoc\pandoc -s -o --mathjax test.html test.md
如果把pandoc.exe加入了Windows操作系统的Path环境变量中, 上面的 C:\Pandoc\pandoc 可以简写为 pandoc。
pandoc在其它操作系统中也有相应的版本。 软件下载与文档见Pandoc的网站http://pandoc.org。
如果使用RStudio编辑markdown文件或者R Markdown文件, 它会自动调用内置的pandoc程序。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
22 R Markdown文件格式
22.1 R Markdown文件
借助于R的knitr和rmarkdown扩展包的帮助, 可以在Markdown格式的源文件中插入R代码, 使得R代码的结果能够自动插入到最后生成的研究报告中。 这种格式称为R Markdown格式,简称为Rmd格式, 相应的源文件扩展名为.Rmd。 输出格式可以是HTML、docx、pdf、beamer等。 R Markdown的基础格式是markdown格式, 严格说来是Pandoc软件支持的增强版的markdown格式, 比如, 支持LaTex格式的数学公式, 支持各种编程语言语法彩色加亮显示,等等。
knitr的详细文档参见网站knitr文档。 关于R Markdown可参考专著(Xie, Allaire, and Grolemund 2019)。 RStudio网站提供了一个R Markdown使用摘要下载: (rmarkdown-2.0.pdf)[rmarkdown-2.0.pdf]。 Pandoc的文档见pandoc网站。
一个Rmd文件中包含元数据(metadata)、正文内容和R代码三种成分, 比如,下面是一个简单的Rmd文件样例:
title: "R语言简介"
author: "李东风"
date: "2019-08-29"
output: html_document
这里是正文段落。
段落中仍可以利用一般的Markdown语法,
比如在两边用双星号表示粗体加重 ,
在用两边反单撇号表示代码,如y <- sin(x)。
下面是一个R代码段,有文字输出:
{r} set.seed(1) x <- round(rnorm(10), 2) print(x)
下面是一个R代码段,有图形输出:
{r} plot(x)
下面是一个R代码段,
有富文本表格输出:
{r} knitr::kable(as.data.frame(x))
在文字段落内部也可以有代码,
比如,x的第一个元素值为r x[1]。
```
在文件开头用三个减号组成的行包围的内容称为元数据, 可以用来规定文章标题、作者、日期、输出格式、输出设置等属性。 见22.11。
22.2 R Markdown文件的编译
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。 用快捷图标Knit可以将文件转换成HTML格式、PDF格式(需要安装LaTeX编译软件)、MS Word格式。
从HTML格式可以转换成PDF格式。 为此, 安装Google的Chrome浏览器, 在Chrome中打开HTML文件后, 从Chrome浏览器的菜单中找到打印菜单, 从中选择打印机为"保存到PDF"选项, 就可以将HTML网页转换成PDF, 其中的数学公式、表格、图形都可以比较好地转换。 但是,经试验,slidy幻灯片用Internet Explorer浏览器转换PDF更合适。 其它浏览器在转换数学公式时容易将公式右侧的编号裁切掉。
从Word文件也可以转换成PDF格式, 用MS Word软件的"文件-导出"或者"文件-另存为"功能即可。
如果想将R Markdown文件借助于LaTeX格式转换为PDF, 需要在系统中安装一个TeX编译器, 如MS Windows下有MikTeX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包。
如果不借助于RStudio软件, 可以用R软件、knitr包、rmarkdown包、pandoc软件来完成R Markdown源文件的编译。 比如,假设test.Rmd是一个这样的R Markdown格式的文件, 注意一定要使用UTF-8编码保存, 可以在R或RStudio中运行如下命令以生成含有运行结果的html文件:
rmarkdown::render("myfile.Rmd", output_format = "html_document", encoding="UTF-8")
其中myfile.Rmd是源文件, 产生的HTML文件带有图形、支持数学公式。
在R或RStudio中可以用如下命令把.Rmd文件转化为MS Word docx格式:
rmarkdown::render("myfile.Rmd", output_format = "word_document", encoding="UTF-8")
使用RStudio软件使得这些任务可以一键完成, 而且有很好的数学公式支持, 所以建议编辑R Markdown文件还是使用RStudio软件。
用RStudio的Knit图标一键编译与用rmarkdown::render()命令编译有一个重要差别:
用Knit图标编译,Rmd文件中的程序会在一个崭新的会话中执行, 当前会话中已经定义的函数、变量、导入的扩展包不会影响到编译结果;
用rmarkdown::render()编译, Rmd文件中的程序是在当前会话中执行的, 会带来一定的兼容性问题, 有可能在别人的环境下就不能正确执行或者会给出不同结果。 但是,rmarkdown::render()可以通过程序调用, 比如,循环地从同一个Rmd生成一系列不同的报告。 为了不让当前会话环境干扰结果, 可以人为地打开一个新会话。
22.3 在R Markdown文件中插入R代码
插入的R代码分为行内代码与代码块。
行内代码的结果插入到一个段落中间, 代码以``r开头,以```结尾, 如r sin(pi/2)`在结果中会显示为1。 为了原样显示一个反向单撇号, 可以在两边用双反向单撇号界定并用空格隔开内部的内容。
代码块则把结果当作单独的段落, 按照Markdown格式的规定, 代码块的前后需要有空行, 但是R Markdown实际上放松了这个要求, 允许前后不空行。 R代码段以单独的一行开头, 此行以三个反单撇号开始, 然后是{r},如````{r}`。 代码段以占据单独一行的三个反单撇号`````结尾。 如
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
结果将变成
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
[1] -0.63 0.18 -0.84 1.60 0.33 -0.82 0.49 0.74 0.58 -0.31
可以看出,代码段程序会被插入到最终结果中, 代码段的文本型输出会插入到程序的后面。
代码块也可以嵌入到引用、列表等环境中。
代码块中作的图将自动插入到当前位置。 下面的程序:
plot(x)
结果将显示为:
plot(x)
img
在RStudio中, 可以用Insert快捷图标插入代码段, 还可以用Ctrl+Alt+I快捷键插入代码段。
22.4 输出表格
knitr包提供了一个 kable() 函数可以用来把数据框或矩阵转化成有格式的表格, 支持HTML、docx、LaTeX等格式。
例如,计算线性回归后, summary()函数的输出中有coefficients一项,是一个矩阵, 如果直接文本显示比较难看:
x <- 1:10; y <- x^2; lmr <- lm(y ~ x)
co <- summary(lmr)$coefficients
print(co)
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函数来显示:
knitr::kable(co)
Estimate Std. Error t value Pr(>|t|)
(Intercept) -22 5.5497748 -3.964125
x 11 0.8944272 12.298374
kable()函数的digits=选项可以控制小数点后数字位数, caption=选项可以指定表的标题内容。
R扩展包xtable提供了一个xtable()函数, 也可以用来生成HTML格式和LaTeX格式的表格, 但是需要指定要输出的格式。 xtable对比较多的R数据类型和输出类型提供了表格式显示功能, 包括矩阵、数据框、回归分析结果、方差分析结果、主成分分析结果、 若干分析结果的summary结果等。 例如,上面的回归结果用xtable()函数显示如:
print(xtable::xtable(lmr), type='html')
Estimate Std. Error t value Pr(>|t|)
(Intercept) -22.0000 5.5498 -3.96
x 11.0000 0.8944 12.30
这个代码段用了选项results='asis', 因为xtable生成的是直接用来插入到结果中的html代码。 注意这里指定了输出为HTML类型。 如果将本文件转化为docx, xtable的结果不可用。
R扩展包pander提供了更好的表格能力, 也能与knitr包很好的合作输出。 其pander()函数可以将多种R输出格式转换成knitr需要的表格形式。 如
pander::pander(lmr)
Estimate Std. Error t value Pr(>|t|)
(Intercept) -22 5.55 -3.964
x 11 0.8944 12.3
但是,经过试验发现, 表中中有中文时pander包会出错。
22.5 利用R程序插图
Rmd文件的插图有两种, 一种是已经保存为图形文件的, 主要是png和pdf图片; 另一种是文中的R代码生成的图形。
已经有图形文件的, 可以用markdown格式原来的插图方法, 见markdown格式介绍。 但是,这样做不能给图形自动编号, 另外因为制作图书是有网页和PDF书两种主要输出格式的, 原有的插图方式在这两种输出格式上有细微的不一致。 所以,最好是统一使用Rmd的插图方法。
Rmd的插图方法就是写一段R代码段来插图, 如果是用程序作图,则代码中写作图的代码; 如果是已有的图形文件, 可以在一个单独的R代码段中用类似下面的命令插图:
{r, echo=FALSE} knitr::include_graphics("figs/myfig01.png")
knitr::include_graphics("figs/myfig01.png")
其中figs是存放图形文件的子目录名, myfig01.png是要插入的图形文件名。 这样, 如果同时还有myfig01.pdf的话, 则HTML输出使用png图片而PDF输出自动选用pdf文件。 另外, 插图的选项在代码段的选项中规定: 用代码段的fig.with和fig.height选项指定作图的宽和高(英寸), 用out.width和out.height选项指定在输出中实际显示的宽和高, 实际显示的宽和高如果使用如"90%"这样的百分数单位则可以自动适应输出的大小。
由于PDF中的中文编码不能自动识别, 所以在每个Rmd源文件的开头应该加上如下的设置, 使得生成PDF图时中文能够正确显示:
{r setup-pdf, include=FALSE} pdf.options(family="GB1")
其中include=FALSE表示要不显示代码段的代码, 有运行结果也不插入到输出结果中, 是否运行视缺省的eval=的值而定。
22.6 代码段选项
独立代码段以````{r}开头, 在大括号内还可以写一些选项, 选项之间以及与开始的r之间用逗号分隔, 所有选项写在同一行内不要换行。 选项都使用"选项名=选项值"的格式, 选项值除了使用常量外也可以使用全局变量名或表达式。 在大括号内开头的r`空格后写一个由英文大小写字母、数字、减号组成的标识符, 作为代码段的标签。 标签中不要用其它类型的字符, 下划线也不要用。 如
{r firstCode} cat('This is 第一段, 有标签.\n')
关于代码段选项, 详见https://yihui.name/knitr/options。
22.6.1 代码和文本输出结果格式
R代码块和R代码块的运行结果通常是代码块原样输出, 运行结果用井号保护起来, 这样有利于从文章中复制粘贴代码。 如:
{r} s <- 0 for(x in 1:5) s <- s + x^x s
结果为:
s <- 0
for(x in 1:5) s <- s + x^x
s
[1] 3413
22.6.1.1 highlight选项
转化后的R代码块缺省显示为彩色加亮形式。 用选项highlight=FALSE关闭彩色加亮功能。
22.6.1.2 prompt和comment选项
如果希望代码用R的大于号提示符开始, 用选项prompt=TRUE。 如果希望结果不用井号保护, 使用选项comment=''。 例如:
{r prompt=TRUE, comment=''} sum(1:5)
结果为:
sum(1:5)
1\] 15 22.6.1.3 echo选项 如果希望不显示代码, 加选项echo=FALSE。 如
{r echo=FALSE} print(1:5)
结果为:
[1] 1 2 3 4 5
22.6.1.4 tidy选项
加选项tidy=TRUE可以自动重新排列代码段, 使得代码段格式更符合规范。例如:
{r tidy=TRUE} s <- 0 for(x in 1:5) {s <- s + x^x; print(s)}
结果为:
s <- 0
for (x in 1:5) {
s <- s + x^x
print(s)
}
[1] 1
[1] 5
[1] 32
[1] 288
[1] 3413
22.6.1.5 eval选项和include选项
加选项eval=FALSE, 可以使得代码仅显示而不实际运行。 这样的代码段如果有标签, 可以在后续代码段中被引用。
加选项include=FALSE, 则本代码段仅运行, 但是代码和结果都不写入到生成的文档中。
22.6.1.6 child选项
加选项child='文件名.Rmd'可以调入另一个.Rmd文件的内容。 如果有多个.Rmd文件依赖于相同的代码,可以用这样的方法。
22.6.1.7 collapse选项
一个代码块的代码、输出通常被分解为多个原样文本块中, 如果一个代码块希望所有的代码、输出都写到同一个原样文本块中, 加选项collapse=TRUE。 例如, 没有这个选项时:
{r} sin(pi/2) cos(pi/2)
结果为:
sin(pi/2)
[1] 1
cos(pi/2)
[1] 6.123032e-17
代码和结果被分成了4个原样文本块。 加上collapse=TRUE后,结果为:
sin(pi/2)
[1] 1
cos(pi/2)
[1] 6.123032e-17
代码和结果都在一个原样文本块中。
22.6.1.8 results选项
用选项results=选择文本型结果的类型。 取值有:
markup, 这是缺省选项, 会把文本型结果变成HTML的原样文本格式。
hide, 运行了代码后不显示运行结果。
hold, 一个代码块所有的代码都显示完, 才显示所有的结果。
asis, 文本型输出直接进入到HTML文件中, 这需要R代码直接生成HTML标签, knitr包的kable()函数可以把数据框转换为HTML代码的表格。
例如:results='hold'的示例:
{r collapse=TRUE, results='hold'} sin(pi/2) cos(pi/2)
结果为:
sin(pi/2)
cos(pi/2)
[1] 1
[1] 6.123032e-17
22.6.1.9 错误信息选项
选项warning=FALSE使得代码段的警告信息不进入编译结果, 而是在控制台(console)中显示。 有一些扩展包的载入警告可以用这种办法屏蔽。
选项error=FALSE可以使得错误信息不进入编译结果, 而是出错停止并将错误信息在控制台中显示。
选项message=FALSE可以使得message级别的信息不进入编译结果, 而是在控制台中显示。
22.6.2 图形选项
22.6.2.1 图形大小
用fig.width=指定生成的图形的宽度, 用fig.height=指定生成的图形的高度, 单位是英寸(1英寸等于2.54厘米)。
下面给出一个长宽都是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)
img
fig.width=和fig.height=规定的是生成的图形大小, 实际生成图形的显示大小会受到dpi(分辨率)影响, 默认dpi是72(每英寸72个点), 也可以用dpi=选择分辨率。 转化后的HTML文件显示时不一定按原始大小显示。 用out.width=和out.height=可以指定显示大小, 但是必须是最终文件格式承认的单位, 比如HTML的图形大小单位是点(平常说屏幕分辨率的单位)。 或者写成如90%这样的百分比格式。 例如在上面的例子中加上输出度为页面宽度80%的选项:
{r fig.width=10/2.54, fig.height=10/2.54, out.width="80%"} 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)
img
当输出结果为HTML结果或者LaTeX转换的PDF时, 只要两个图形的总宽度小于页面宽度, 两个连续的图形就可以左右并列放置。 Word不支持这种功能。 例如:
{r, echo=FALSE, fig.width=10/2.54, fig.height=10/2.54, out.width="45%"} curve(exp(-0.1*x)*sin(x), 0, 2*pi) abline(h=0, lty=3) curve(exp(-0.1*x)*cos(x), 0, 2*pi) abline(h=0, lty=3)
结果为
imgimg
22.6.2.2 图形结果选择
用fig.keep=选项可以选择保留哪些R代码生成的图。 缺省是fig.keep='high', 即保留每个高级图形函数的结果图形, 低级图形函数对高级图形函数的更改不单独保存而汇总到高级图形函数结果中。 如
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, 所有图都不显示出来。
22.6.3 缓存(cache)选项
当R Markdown文章比较长,包含的R代码比较多, 或者代码段运行需要比较长时间时, 反复编译整篇文章会造成不必要的计算, 因为有些代码段并没有修改, 依赖的数据也没有改变。 knitr提供了缓存功能, 代码段选项cache=TRUE对代码段打开缓存, 允许暂存上次运行的结果(包括文本结果和图形) 而不需要重复运行代码段。 当代码段被修改时, 缓存被放弃, 编译时重新运行代码段。
缓存这种功能需要慎重使用, 免得错误地使用了旧的结果。 当后面的代码段需要使用前面代码段结果时, 如果前面结果改了, 后面的代码段就不能使用缓存的结果而必须重新计算。 为此, 在后面的代码段中应该加上dependson=选项, 比如dependson=c('codeA', 'codeB'), 其中codeA和codeB是前面的缓存了的代码段的标签, 其结果会用在本代码段中。 也可以使用代码段选项autodep=TRUE, knitr试图自动确定前后代码段之间的依赖关系, 每当前面的代码段改变时, 后面的用到其结果代码段也自动重新计算而不使用缓存的旧结果。
建议仅对计算一次需要较长时间的代码段使用缓存功能, 后面依赖于其结果的代码一定要加上dependson=选项。 建议代码段尽可能有标签,这样在编译失败时能马上看出失败的地点。
为了保险起见, 可以尽量不使用缓存功能, 而是用save()功能将需要长时间结算的结果保存下来, 用load()载入然后输出到结果文档中。
22.7 章节目录链接问题
对于英文文件, R Markdown基于的pandoc软件可以自动从标题生成适当的链接标签, 将HTML输出或者PDF输出设置属性toc: true后可以生成可点击的章节目录。 但是,目前Pandoc对于中文文件的支持差一些, 所以中文文件要自动生成可点击的目录, 需要在每个标题行的末尾,空格后添加{#label}, 其中label是自己指定的标签内容, 但是建议仅使用英文字母、数字、减号。 如
第三章第一节标题 {#c3-s1-int}
如果希望某个标题不参与自动编号, 可以在标题末尾空格之后加上{-}标记。
22.8 数学公式
22.8.1 在Markdown中输入数学公式
原始的Markdown格式并不支持数学公式。 Pandoc扩展的markdown格式提供了对数学公式的支持, 可以在Markdown文件中插入LaTeX格式的数学公式。 虽然不能提供所有的LaTeX公式能力, 但是常用的数学公式还是能做得很好, 转换到HTML、docx都可以得到正常显示的公式。
用RStudio软件编译Markdown文件,可以在其中插入LaTeX格式的数学公式, 编译成HTML或者docx格式后都可以正常显示数学公式, 在另外安装的LaTeX编译器的支持下也可以将.Rmd格式编译LaTeX格式然后再转换为PDF格式, 这种方法对数学公式的支持会更完善。
关于数学公式的软件设置参见下面设置部分的内容。
22.8.2 数学公式类别
数学公式公式分为行内公式和独立公式。 行内公式和段落的文字混排, 写在两个美元符号KaTeX parse error: Can't use function '\(' in math mode at position 6: 中间,或者\̲(̲和\)之间。 例如f(x)=\frac{1}{2} \int_0^1 \sin^2 (t x) dt 变成。开头的 变成 。 开头的 变成。开头的后面不能紧跟着空格, 结尾的$不能紧跟在空格后面。
独立公式写在成对的美元符号中间,或者[和]之间。 例如:
f ( x ) = 1 2 ∑ j = 1 ∞ ∫ 0 1 sin 2 ( j t x ) d t . f(x) = \frac{1}{2} \sum_{j=1}^\infty \int_0^1 \sin^2(j t x) dt . f(x)=21j=1∑∞∫01sin2(jtx)dt.
显示为
22.8.3 基本功能
在数学公式中, 用下划线表示下标, 比如 x 1 x_1 x1结果为。 用^表示上标, 如 x 2 x^2 x2结果为。 上下标都有,如 x 1 2 x_1^2 x12结果为。
公式中用大括号表示一个整体, 比如 x ( 1 ) x^(1) x(1)不能得到, 需要用 x ( 1 ) x^{(1)} x(1)。
公式中用反斜杠开始一个命令, 命令仅包含字母而不能包含数字, 数字只能作为参数。 如 1 2 \frac{1}{2} 21和 1 2 \frac12 21都可以生成。 类似的命令如 2 \sqrt{2} 2 为。
希腊字母都有对应的命令, 如 α \alpha α为, Σ \Sigma Σ为。
常用数学函数有自己的命令, 如 sin x \sin x sinx变成, exp ( x ) \exp (x) exp(x)为。
圆括号与方括号可以直接使用, 绝对值符号用|, 如 ∣ x ∣ |x| ∣x∣变成。 但是,大括号必须写成{和}的形式, 如 exp { − 1 2 x 2 } \exp\{-\frac12 x^2\} exp{−21x2}变成。
为了使得括号能够与括号内部的内容等高, 可以用\left和\right命令进行修饰, 如
ϕ ( x ) = 1 2 π exp { 1 2 x 2 } \phi(x) = \frac{1}{\sqrt{2\pi}} \exp\left\{ \frac{1}{2} x^2 \right\} ϕ(x)=2π 1exp{21x2}
变成
注意\left``\right
求和如 ∑ i = 1 n x i \sum_{i=1}^n x_i ∑i=1nxi变成。 乘积如 ∏ i = 1 n x i \prod_{i=1}^n x_i ∏i=1nxi变成。 积分如 ∫ 0 1 f ( x ) d x \int_0^1 f(x) dx ∫01f(x)dx变成。
22.8.4 修饰符
f ′ ( x ) f'(x) f′(x)显示为, 表示导数; f ′ ′ ( x ) f''(x) f′′(x)显示为, 表示二阶导数。 顺便说一句, 偏导数写法如 ∂ f ( x , t ) ∂ x \frac{\partial f(x,t)}{\partial x} ∂x∂f(x,t), 显示为。
的写法是 x ˉ \bar{x} xˉ。 的写法是 span ‾ \overline{\text{span}} span。 的写法是 x ^ \hat{x} x^。 的写法是 x ~ \tilde{x} x~。 的写法是 x ⃗ \vec{x} x 。
22.8.5 对齐与矩阵
为了产生对齐的公式, 在独立公式中使用aligned环境。 公式中的环境以\begin{环境名}开始, 以\end{环境名}结束, 用\表示换行,用&表示一个上下对齐位置。 如
f ( x ) = ∑ k = 0 ∞ 1 k ! x k = e x \begin{aligned} f(x) =& \sum_{k=0}^\infty \frac{1}{k!} x^k \\ =& e^x \end{aligned} f(x)==k=0∑∞k!1xkex
转化成
可以用pmatrix环境制作写在圆括号中的矩阵, 用bmatrix环境制作写在方括号中的矩阵, 用vmatrix制作写在绝对值号中的矩阵,如
列向量、行向量也可以用这种办法制作。
22.8.6 特殊字体
数学公式中的单词、文字必须用\text{...}保护,比如
CV = S x ˉ × 100 % \text{CV} = \frac{S}{\bar x} \times 100 \% CV=xˉS×100%
变成
上例中如果不用\text{}
有时用粗体表示向量或者矩阵, 用\boldsymbol{...}说明。如
v = ( v 1 , v 2 ) T \boldsymbol{v} = (v_1, v_2)^T v=(v1,v2)T
变成
美术体英文字母用\mathcal{...}, 如写法为 A , B , C \mathcal{A, B, C} A,B,C。
手写花体字母用\mathscr{...}, 如写法为 B , C , F , G \mathscr{B, C, F, G} B,C,F,G。
22.9 其它编程语言引擎
Rmd文件中除了R代码段以外, 还可以插入Rcpp、Python、Julia、SQL等许多编程语言的代码段, 常用编程语言还可以与R代码段进行信息交换。
22.10 交互内容
在Rmd生成HTML结果时, 可以在结果中包含允许读者交互操作的内容, 比如, 用户修改模型参数, 使得模型报表、图形交互地改变。 有两种方法可以实现交互:
HTML小程序(widgets), 由R扩展包htmlwidgets实现, 利用JavaScript函数库进行交互。 在这一功能基础上有一些派生的扩展包, 如DT,leaflet, dygraph。
利用shiny框架,这也是一个R扩展包, 交互功能由R的一个会话驱动。 Rmd文件的YAML元数据中需要设置runtime: shiny。
22.11 属性设置
22.11.1 YAML元数据
可以在RStudio软件中编辑markdown文件与Rmarkdown文件, RStudio的markdown支持来自knitr、rmarkdown、bookdown扩展包和pandoc软件, .Rmd文件支持一些特殊的文件设置, 这些设置写在markdown文件和.Rmd文件的开头位置, 用三个减号组成的行作为开始标记与结束标记, 称为YAML元数据块(YAML meta data block), 块后面必须用空行分隔。 元数据块中可以用"设置属性名: 设置属性值"的办法设置属性, 用缩进表示属性内容,用上下对齐的行表示多项列表。 常用属性有title(标题)、author(作者)、date(日期)、output_format(输出格式)等,如
title: "临时测试"
author: "李东风"
date: "2016年7月6日"
这三个设置会出现在转换后结果的标题部分。 RStudio的中文支持还是有时出现问题, 如果出现涉及到YAML的错误, 先将中文内容替换为英文试一试。
因为冒号:在属性设置中有特殊意义, 属性设置值如果含有冒号, 需要把整个属性值两边用单撇号界定。
属性值可以是列表或多项,例如:
title: 'This is the title: it contains a colon'
author:
- name: Author One
affiliation: University of Somewhere - name: Author Two
affiliation: University of Nowhere
tags: [nothing, nothingness]
abstract: |
This is the abstract.
It consists of two paragraphs.
此例中有title、author、tags、abstract四个属性。 author属性包含两个作者, 每个作者又有name和affiliation两个属性。 tags属性是一个两项的列表。 abstract属性用管道符号|表示开头,不需要结束标志,内容缩进。
22.11.2 输出格式
.Rmd文件开头的YAML元数据中, 属性output选择输出的格式, 如
html_document是HTML输出;
pdf_document是PDF输出,通过系统中另外安装LaTeX编译系统转换;
word_document是docx格式的Word文件输出,等等。
输出格式指定如:
output:
html_document: default
word_document: default
pdf_document: default
其中default表示该输出格式完全使用默认设置。 在输出格式没有定制设置时必须有default指定。
22.11.3 输出格式设置
在每种输出格式后面还可以继续添加该输出特有属性。 如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
pdf_document:
toc: true
22.11.4 目录设置
输出格式的toc: true选项指定自动生成目录, HTML输出、PDF输出、Word输出都支持此功能。 见上例。
output:
html_document:
toc: true
toc_depth: 2
上例中,html_document是output的属性, 隶属关系用缩进表示; html_document又有自己的属性toc和toc_depth, 隶属关系用缩进表示。 属性toc: true表示要自动生成可点击的目录。 输出格式的属性toc_depth是目录包含的章节层级数。
对html_document输出, 属性toc_float: true使得生成的文档在左侧显示一个目录导览窗格。 而toc_float属性又可以指定一些属性,隶属关系用缩进表示。 toc_float的属性collapse: true表示仅展开章节第一层级, smooth_scroll: true使得通过导览窗格跳跃时页面有平滑滚动过程显示。 用如:
output:
html_document:
toc: true
toc_float:
collapse: true
smooth_scroll: true
22.11.5 章节自动编号
输出格式的属性number_sections为true可以自动对章节编号。 HTML输出与PDF输出都支持此功能。
在章节自动编号时, 如果不是利用bookdown包而是基于基本的R Markdown, 文中的分节最高层级最好用一个井号, 对应于节, 如果用两个井号, 编号会变成0.1,0.2这样。
22.11.6 Word输出章节自动编号及模板功能
Word文件不能自动编号, 解决办法是生成适当的模板文件, 如wordstyle.docx, 然后在Rmd文件的元数据部分为word_document输出增加reference_docx选项,如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
reference_docx: wordstyle.docx
这样,新编译的Rmd文件就可以采用wordstyle.docx的格式设置, 比如章节自动编号等。 目前目录标题还是英文, 需要在结果中人为地修改为中文。 一个样例模板下载如下: wordstyle.docx
22.11.7 HTML特有输出格式设置
对于html_document输出类型, 可以用theme属性设置一个主题, 取值如default, cerulean, journal, flatly, darkly, readable, spacelab, united, cosmo, lumen, paper, sandstone, simplex, yeti。
用highlight属性设置程序语言语法高亮样式, 可取值有default, tango, pygments, kate, monochrome, espresso, zenburn, haddock, and textmate。 用null表示取消语法高亮。
可以用css属性指定一个自定义的CSS样式表文件。 如果希望完全用自己的样式代替原有样式, 可以设置theme: null。
code_folding属性设置HTML结果中代码折叠选项, 取值hide可以隐藏代码, 但读者通过选项可见。 取值show可以显示代码, 但读者通过选项可隐藏代码显示。
22.11.8 关于数学公式支持的设置
Rmd格式支持数学公式, 在生成的HTML、Word、PDF中都可以正常显示数学公式。
以HTML为输出时, 会使用MathJax库显示数学公式。 这是一个用于在浏览器中显示数学公式的Javascript程序库, 显示效果很好, 还支持多种显示实现方式, 支持包括LaTeX在内的多种数学公式输入方法。
MathJax库很大, 所以一般是从其网站按需远程调用的, 但是远程调用MathJax库在网络不畅通时会使得公式显示极为缓慢甚至无法显示, 所以Rmd允许将MathJax本地化。 在.Rmd文件头部YAML元数据的某种HTML输出格式的属性中, 设置属性mathjax: local和就可以使得MathJax库被放在生成的HTML的一个下层目录中。 设置如
output:
html_document:
toc: true
self_contained: false
mathjax: local
注意设置mathjax: local同时必须设置self_contained: false。 在不使用本地MathJax副本时, 可以设置self_contained: true, 这使得图形文件、JavaScript代码等依赖项也打包在生成的单一HTML文件中, 如果设为false, 这些依赖文件会存放在单独文件中。 可以用lib_dir属性指定一个子目录用来存放这些依赖文件, 多个Rmd文件可以共用同一个lib_dir值。
将MathJax用mathjax: local属性本地化有明显的缺点。 这时,每个Rmd项目都需要一个MathJax库副本, 使得文件备份变得很麻烦。 下面的设置方法可以令多个Rmd项目共享一个共同的本地MathJax库。
22.11.9 输出设置文件
如果一个项目包含多个.Rmd文件, 每个文件单独用YAML元数据进行设置比较繁琐, 修改时也很麻烦。 可以在项目目录中增加一个_output.yml文件, 其中包含所有.Rmd文件共用的output属性的设置, 各个.Rmd文件还可以有自己单独的output属性, .Rmd文件YAML元数据中的属性优先级高于共同设置的属性。
例如,_output.yml文件内容如下:
html_document:
toc: yes
number_sections: yes
mathjax: ".../.../MathJax/MathJax.js"
includes:
in_header: "_header.html"
word_document:
toc: yes
reference_docx: wordstyle.docx
pdf_document:
includes:
in_header: preamble.tex
latex_engine: xelatex
上面设置了使用本地硬盘的MathJax库, 位于项目目录的上两层目录中的MathJax子目录中。 这样可以使得多个项目共享一个MathJax库。 将生成的结果当作网站发布时, 只要将MathJax库也安装到项目在网站的目录的上两层的MathJax子目录中就可以。 其中_header.html内容如下,是关于MathJax具体的一些设置:
注意, _output.yml文件都是输出设置, 所以不能再有output属性,所以下面的_output.yml写法是不正确的:
output:
html_document:
toc: yes
22.12 LaTeX和PDF输出
Rmd文件的pdf_document输出类型是先转换为LaTeX文件, 再借助计算机系统中另外安装的LaTeX编译程序转换为PDF。 需要在系统中安装一个TeX编译器, MS Windows下有MikTeX软件包或者CTEX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包, 优点是直接用R命令就可以安装, 更新也由R自动进行,不需要用户干预。
许多LaTeX相关的YAML元数据不是设置在输出属性中, 而是设置为文件的顶级元数据。 如
其中属性fontsize和geometry都是LaTeX选项, 但是没有作为output--pdf_document的属性, 而是作为Rmd文件的顶级元数据属性。
用属性documentclass指定LaTeX文档类型, 比如article是论文格式, book是图书格式。 ctexart和ctexbook是适用于中文的格式。
fontsize是正文字体大小, 可取10pt, 11pt, 12pt, 其中10pt是缺省大小。
geometry用来指定geometry包的参数。
默认的LaTeX编译引擎是pdfLaTeX。 可以在pdf_document输出的属性中设置latex_engine: xelatex将引擎替换成xeLaTeX。 xeLaTeX的优点是支持UTF8编码,可以使用系统中现有字体, 而我们在写中文的R Markdown文档时必须使用UTF-8编码。
Rmd文件中的文献引用可以由pandoc软件执行, 但是在用LaTeX转换PDF时, 可以指定用一个LaTeX引用包, 如:
output:
pdf_document:
latex_engine: xelatex
citation_package: natbib
为了自动生成目录并自动为章节编号, 仍在pdf_document的属性中指定toc: true和number_section: true。
在使用bookdown管理Rmd文件时, 文献引用、目录、章节编号方式有另外的指定办法以及默认规则。
为了能够检查转换过程中的错误, 可以用pdf_document的属性keep_tex: true, 保留作为中间结果的.tex文件, 人工检查其中的错误。
可以在pdf_document输出的属性中指定若干个.tex文件插入到LaTeX文档的导言、正文最前面、正文最后后面,如
output:
pdf_document:
latex_engine: xelatex
keep_tex: true
citation_package: natbib
toc: true
number_sections: true
includes:
in_header: preamble.tex
before_body: doc-prefix.tex
after_body: doc-suffix.tex
preamble.tex主要用来载入额外的LaTeX包以及定义新的命令, 一个preamble.tex的例子如下
不支持百分号,只能去看原文档了。
http://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/index.html
22.13 生成期刊文章
节22.12的办法可以用来生成LaTeX然后转换为PDF, 可以用来撰写学位论文和期刊论文。 但是学位论文和期刊论文都有比较严格的格式要求, 用节22.12的一般方法需要对LaTeX比较熟悉才能达到格式要求。
用R扩展包rticles可以比较容易地将Rmd文件转换成期刊可接受的LaTeX和PDF格式。 见https://bookdown.org/yihui/rmarkdown/journals.html。 扩展包中对一些常见期刊提供了模板。
首先要安装rticles扩展包,命令为
install.packages("rticles")
为了生成新的论文源文件, 在RStudio中, 用"File -- New File -- R Markdown -- from Template"菜单, 从列出的文章模板中选一个。
杂志投稿的Rmd模板是用许多元数据来规定格式的。 用户可以修改其中的标题、作者、作者单位等信息。
因为rticlels的输出只有PDF, 所以必要时可以在Rmd源文件中直接使用LaTeX命令, 但如果Rmd本身可以完成时尽可能用Rmd的功能。
因为定理、图表自动标号和索引功能是由bookdown包提供的, 而rticles的输出类型实际是rmarkdown::pdf_docment, 所以可以联合使用bookdown与rticles,如
output:
bookdown::pdf_book
base_format: rticles::peerj_article
其中peerj_article可以替换成rticles提供的其它格式。
如果自己需要的模板rticles没有提供, 可以自己设法定义模板, 参见https://bookdown.org/yihui/rmarkdown/document-templates.html。
22.14 附录:经验与问题
22.14.1 Word模板制作
如果有合适的Word格式样例, 可以在YAML元数据的word_document的属性中, 设置reference_docs属性指向该模板文件。
为了制作Word模板, 不应该从头开始, 而是在没有模板的情况下从Rmd文件转换生成一个Word文件, 将其作为模板文件的基础进行修改。 在修改过程中, 应该制作过程的备份,以便修改错误时能退回上一个版本。
如果文章的大标题样式不是"标题", 将样式改为"标题"以免在后续的自动编号过程中参与编号。 修改的方法是选中大标题, 然后在Word软件主菜单的"开始--样式"选择框中选中"标题", 就可以设置其样式。
Word的目录是与"标题1"同级的, 这样会在自动编号时参与编号; 为此, 选中"Contents", 然后在主菜单的"开始--样式"选择框中, 找到突出显示的"TOC标题", 右键单击"修改", 在弹出的对话框中将"样式基准"从"标题1"改为"标题", 并在同一对话框中将适当调整样式, 如字体类型、大小、颜色、是否居中。 改完后保存并保存一个副本。
如果需要修改"标题","作者","日期","标题1"等等的字体、大小、颜色、对齐方式, 可以选中该部分,并在"样式"中邮件单击相应的样式,选择"修改"进行修改, 保存样式文件并试验Rmd文件是否正确地利用了修改的样式。
为了实现自动编号, 先在正文中选中一个一级标题(不能是目录标题), 从Word的主菜单栏找到"开始------段落------多级列表------定义新的多级列表", 在打开的对话框中点击"更多"选项, 逐一地选择"单击要修改的级别", 将级别1、2、3等分别修改, 主要是修改"将级别链接到样式"使得"级别1"与"标题1"对应, "级别2"与"标题2"对应,等等。 注意这个修改要一次性完成, 不能保存了文件后再次定义新的多级列表。
修改模板文件的页边距也会使得利用其为模板的Rmd文件转换结果被修改。 为了修改模板文件的页边距, 在主菜单"布局------页边距------自定义页边距"弹出的对话框中修改。
生成的目录的标题内容是"Table of Contents", 目前只能对Rmd输出的docx文件直接修改, 修改模板文件的标题内容并不能使得Rmd输出被修改。
参考:Richard Layton的网站文章 https://rmarkdown.rstudio.com/articles_docx.html。
22.14.2 数学公式设置补充
如果不使用RStudio, R扩展包rmarkdown的markdownToHTML()函数可以把含有数学公式的内容转换成可显示公式的HTML文件, R扩展包knitr的knit2html()也可以实现此功能。 用rmarkdown扩展包的markdownToHTML()函数生成的含有数学公式的内容。
单独使用pandoc软件时, 也可以用普通文本编辑器在Markdown文件中输入LaTeX格式的数学公式, 然后用pandoc软件转化为带有数学公式的docx文件, 不需要额外选项。 但是,为了能够在转换的HTML文件中正常显示数学公式, 需要在运行Pandoc时增加运行选项--maxjax,如
pandoc --mathjax -s -o test.html test.md
经试验,这样转化的HTML文件可以在Firefox以及Microsoft的 Edge浏览器和Internet Explorer浏览器中正常显示数学公式。 如果公式中的中文显示不正常, 对显示的公式右键单击弹出选项菜单, 选择"Math Settings--Math Renderer--SVG"或者"HTML-CSS"。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.---
layout: post
title: "R制作研究报告"
date: 2019-11-29
tag: sas
20 用R制作研究报告
一个统计或数据分析的科研项目, 都会产生一个或多个研究报告。 因为使用统计与数据分析不可避免地有很多计算涉及在内, 这里假设使用R软件做了计算。 科研是一个不断改进的过程, 所以每一次重新做了计算, 研究报告中的汇总表格、图形都要更新。 这样的任务比较繁琐, 也容易出错。
"文学式编程"(literate programming, (Knuth 1984))是这样一种思想, 把撰写报告与计算程序有机地结合在一起, 用一个源文件文件既包含报告内容, 又包含计算程序。 每次产生研究报告时, 先运行源文件中的计算程序得到计算结果, 这些结果包括文字性内容与图形, 然后利用适当软件自动地把这些原始文字、计算结果组合成最终的报告。 利用这样的思想, 可以自动生成重复的例行报告, 还可以作为"可重复科学研究"的载体。
上述的源文件一般是文本文件, 格式可以是Markdown格式, 也可以是LaTeX格式等许多格式。 R的knitr软件包就是用来支持这样的编程思想的一个扩展包。
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名, 利用R程序进行扩展的版本保存为.Rmd扩展名。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。 Markdown仅适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过LaTeX编译器可以转换为PDF格式, 也可以将docx转存为PDF格式, 或者用输出到PDF文件的打印机将网页格式转换为PDF格式。
LaTeX是一个文档排版系统, 功能强大,结果美观, 设计合理。 缺点是需要学习类似于HTML的另一种语言。 LaTeX源文件主要是编译为PDF。
R扩展包knitr包支持在Markdown格式、LaTeX格式等类型的文件中插入R代码, 经过转换, 文中的R代码可以变成代码的结果文字、表格、图形, 与原有报告文字有机地结合在一起。
插入了R代码的markdowng格式的文件一般以.Rmd为扩展名, R的rmarkdown扩展包和knitr包一起为Rmd格式提供了支持。
R的bookdown包进一步增强了R Markdown格式的功能, 支持生成PDF、多文件互相链接的HTML、Word等输出, 其中的表格、图形可以变成浮动表, 公式、定理可以自动编号并支持文献、公式、定理、图表、章节的引用和链接, 所以比较适用于编写一本书或论文、研究报告。
knitr包也支持在LaTeX源文件中插入R代码, 通过编译使得R代码运行结果、图形自动插入生成的研究报告中。 原来有一个Sweave扩展包是支持在LaTeX中插入R代码的, 现在knitr的功能已经涵盖并增强了此包功能。
下面几章分别介绍markdown格式、R markdown格式、bookdown扩展包、简易网站制作和幻灯片制作。 参考:
利用R Markdown格式可以执行如下的任务:
- 将单一的R Markdown文件编译为不同的格式,如:
- HTML;
- PDF;
- MS Word。
- 在RStudio软件内制作笔记本文档,可以在其中包含说明文字与R代码, 可以在笔记本文档内交互地运行R代码并能将结果交互地显示在笔记本内。
- 生成演示幻灯片,可以是基于HTML5的,也可以是基于LaTeX beamer扩展包的, 或者MS Powerpoint。
- 编写多章节组成的书籍。
- 编写期刊论文。
- 制作网站或者博客。
- 制作商业智能仪表盘(dashboards),即数据可视化展示。
References
Knuth, Donald E. 1984. "Literate Programming." The Computer Journal 27 (2): 97--111.
Xie, Yihui. 2017. Bookdown: Authoring Books and Technical Documents with R Markdown.
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
21 Markdown格式
21.1 介绍
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名。 Mardown中文内容应该使用UTF-8编码。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。
Markdown适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过docx格式可以转存为PDF格式。 R扩展包knitr、rmarkdown和bookdown与pandoc软件一起大大扩展了markdown格式的适用范围。
如果需要作为一本书发布在网站上或者出版, 可考虑使用R的bookdown扩展包。 如果需要对出版格式进行精确控制, 可考虑用LaTeX格式, LaTeX格式很复杂, 学习比较困难, 但是表达能力强。
21.2 Markdown格式文件的应用
Markdown格式用在一些微博、论坛中作为缺省格式, 用户在网络浏览器软件的输入框中按照markdown格式输入, 网站自动将其转换为html富文本内容显示出来。
因为markdown格式就是纯文本, 而且其格式十分简单, 所以可以仅仅用普通文本编辑器编写markdown格式的文件, 不需要转换为其它格式。
有一些独立运行的编辑软件, 在其中输入了markdown格式文件后, 可以并列地显示转化为html富文本后的结果, 很多还支持自动备份到云服务中。 但是,这些独立运行的编辑器大都有商业因素。 比如,国内的印象笔记软件是提供了云存储的笔记软件, 在其PC端就支持创建markdown格式的笔记, 可以在输入时即时显示html效果。
RStudio软件不是专用的Markdown编辑器, 它是一个R程序的集成编辑、运行环境, 对个人用户免费, 在R Studio中可以编辑Markdown文件和含有R代码的Markdown文件, 可以一键将其转化成HTML、MS Word docx文件, 在单独安装的LaTeX编译软件支持下还可以直接编译成PDF。 RStudio支持下的增强的Mardown格式, 称为RMarkdown格式, 以.Rmd为扩展名, 支持大多数的LaTeX公式, 在bookdown扩展包支持下还支持公式、定理、图表等自动编号和引用、链接。
21.3 markdown格式说明
这部分内容参考了markdown手册和Rstudio的文档, 以及(Xie, Allaire, and Grolemund 2019)。
21.3.1 概述
Markdown格式是John Gruber于2004年创造的, Markdown 的目标是实现"易读易写"。 Markdown定义了一种简单好用的文本文件格式, 作为单独的文本文件, 此格式没有什么多余的标签, 又可以转化为很多其它的格式。
Markdown 的语法全由一些符号所组成, 这些符号经过精挑细选,其作用一目了然。 比如:在文字两旁加上星号,看起来就像强调。 Markdown 的列表看起来就像我们平常在邮件中写一个列表的方法。 Markdown 的区块引用看起来就真的像是引用一段文字, 就像你曾在电子邮件中见过的那样。
需要时, 可以直接在markdown中写HTML标记内容。 markdown能实现的功能是HTML的一部分, 但是比HTML内容更干净, 没有掺杂过多的与要表达的意思无关的标签。 Markdown的理念是,能让文档更容易读、写和随意改。
21.3.2 段落
一个段落由一行或连续的多行组成。 段落之间以空行分隔。 同一段落内的不同行在转换成HTML或docx等格式后会重新排列, 原来的段内换行被当成了空格,这样的规定与LaTeX类似。 普通段落不该用空格或制表符来缩进, 不应在行尾留有空格。
为了在段内换行并且转化后仍保持段内换行, 输入时在前面行的末尾输入两个或两个以上空格。例如:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
显示结果为:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
这样做的缺点是末尾的空格时不可见的。 可以使用HTML的 标签在段内换行,如:
白日依山尽,黄河入海流。<br>
欲穷千里目,更上一层楼。
结果为
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
21.3.3 段内文字格式
在一段内,用星号或下划线包围的内容如*强调*是强调 格式。 用双星号或双下划线包围的内容如**加重**是加重格式。 星号、下划线与要强调或加重的内容之间不要空开, 否则会当作普通星号或下划线解释, 在行首还会当作列表。 为了插入普通的星号或下划线,可以使用反斜杠保护, 或者写成段内代码格式。
可以用一对~作为界定符给出下标, 如HO~2~会变成HO2。 可以用一对^作为界定符给出上标, 如Cu^2+^会变成Cu2+。 但是,数学公式一般还是应该使用LaTeX数学公式形式(见22.8)。
在普通段落内一部分内容希望显示成代码, 对其中的特殊字符不进行解释, 只要包在两个反向单撇号内。 如if(_x_ > 0) y=1;会变成if(_x_ > 0) y=1;。 如果内容本身就包含反向单撇号, 可以在两边使用更多个数的反向单撇号, 如````x` ```会变成x。
在Markdown文件中, 为了使得某些有特殊意义的字符不作特殊解释, 可以在该字符前面加上反斜杠\, 取消其特殊含义。
在Rmarkdown文件中, 为了原样显示反向单撇号, 可以在两边用双写的反向单撇号界定字符串。
21.3.4 标题和分隔线
以一个井号#开始的行是一级标题, 以两个井号#开始的行是二级标题, ............, 以六个井号#开始的行是六级标题。 标题行前面应该空一行, 否则可能把某些偶然出现在行首的#号误认为标题行的标志。
对一级标题, 也可以用标题内容下面输入一行等于号=表示上一行内容是一级标题。 对二级标题, 可以用标题内容下面输入一行减号-表示上一行内容是二级标题。 等于号和减号的个数不限。
用三个或三个以上连续的星号组成的行, 可以转换成分隔线。下面是一个分隔线:
21.3.5 引用段落
可以用类似Email的回复包含原始邮件内容的办法输入引用段落, 即,在段落的每行前面加一个大于号。 比如下面的诗:
> 白日依山尽,黄河入海流。
> 欲穷千里目,更上一层楼。
转换成
白日依山尽,黄河入海流。 欲穷千里目,更上一层楼。
注意引用也是段落模式,内容中的换行不起作用,空行导致分段。
引用段落也可以仅在段落第一行写大于号, 其它行顶格写,例如下面的两段引用:
> 远上寒山石径斜,
白云生处有人家。
>
> 停车坐爱枫林晚,
霜叶红于二月花。
转换成
远上寒山石径斜, 白云生处有人家。
停车坐爱枫林晚, 霜叶红于二月花。
引用也可以嵌套,如:
> 张三说:李四这样说过
>
>> 不想当将军的木匠不是好厨子。
>
转换成
张三说:李四这样说过
不想当将军的木匠不是好厨子。
注意嵌套内容前后都有空的引用行,否则不能实现嵌套引用。
引用内也可以嵌套其它的Markdown格式如标题、列表等。 引用前后应该有空行把引用内容与其他内容分隔开。
21.3.6 列表
列表分为不编号的列表和编号的列表。 不编号的列表转化后通常显示圆点开头的列表项。
在Markdown中, 用星号表示一个不编号的列表项。 星号也可以替换成加号或减号, 后面必须有一个或多个空格。 每个列表项可以输入多行, 各行的内容最好左对齐, 左对齐在使用文本格式时较易阅读, 但不是必须的。 两个列表项之间不要空行。 例如:
* 白日依山尽,
黄河入海流。
* 欲穷千里目,
更上一层楼。
转换为
- 白日依山尽, 黄河入海流。
- 欲穷千里目, 更上一层楼。
段落顶头的数字加句点和空格表示编号列表, 两个列表项之间尽量不要空行。 例如:
1. 第一种解决方法,
收买敌人的高官。
2. 第二种解决方法,
尽可能拖延。
转换为
- 第一种解决方法, 收买敌人的高官。
- 第二种解决方法, 尽可能拖延。
标准的markdown编号列表不能自己定义数字的显示格式, 不允许开始值不等于1。 pandoc支持更自由的列表, 允许输入时有括号或右括号,允许使用字母和罗马数字,但是括号会被去掉。如
(1) 顶层一;
a) 内层二;
b) 内层三;
(2) 顶层二。
转换为
- 顶层一;
- 内层二;
- 内层三;
- 顶层二。
为了避免错误地产生非本意的编号列表, 在行首写数字加句点和空格时,可以在句点前加反斜杠, 或者在句点前加空格。例如,下面是一个年号:
2016\.
如上输入将不会错误地解释为有序列表。
如果列表项目中有多个段落, 这时两个列表项之间应该以空行分隔, 每个项目除了第一行外,输入的每行内容都应该缩进4个空格或者一个制表符。 例如:
* R语言第一个版本开发于1976-1980,基于Fortran;
于1980年移植到Unix, 并对外发布源代码。
1984年出版的"棕皮书"
总结了1984年为止的版本, 并开始发布授权的源代码。
这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新,
变成了我们现在使用的S语言,称为第二版。
1988年出版的"蓝皮书"做了总结。
* 1992年出版的"白皮书"描述了在S语言中实现的统计建模功能,
增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。
现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
转换为
-
R语言第一个版本开发于1976-1980,基于Fortran; 于1980年移植到Unix, 并对外发布源代码。 1984年出版的"棕皮书" 总结了1984年为止的版本, 并开始发布授权的源代码。 这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新, 变成了我们现在使用的S语言,称为第二版。 1988年出版的"蓝皮书"做了总结。
-
1992年出版的"白皮书"描述了在S语言中实现的统计建模功能, 增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。 现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
列表项目内如果有引用段落, 需要都缩进4个空格。 如果有程序代码, 需要缩进4个空格后用三个反单撇号表示开始与结束。
列表可以嵌套, 嵌套的列表需要缩进4个空格, 中间不需要空行。 例如:
1. 第一类工作包括:
+ 技术服务;
+ 咨询服务。
2. 其它工作略。
转换为
- 第一类工作包括:
- 技术服务;
- 咨询服务。
- 其它工作略。
如果需要把每个列表项当作段落排版,可以在每个列表项后空行。
21.3.7 源程序
为了让源程序能够自动显示成源程序的样式, 而不至于自动分行、特殊字符解释, 用空行把源程序与其它内容隔开, 并把源程序行都缩进4个空格(或以上)或者一个制表符。 源程序格式持续到不缩进4个空格的地方为止。
例如,下面的输入:
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
转换为
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
更适当的做法是用三个连续的反向单撇号表示代码开头与代码结束, 中间就会当作源程序代码处理。 例如下面的输入
```
> x <- rnorm(100)
> hist(x)
```
转换为
> x <- rnorm(100)
> hist(x)
R的knitr包在Markdown格式的文件中插入R可执行代码时, 就用了这样的方法。 而且,R Markdown格式的代码块不需要用空行与前后分隔开。
在pandoc程序的支持下, 代码段还可以采用栅栏式代码段, 在代码段开头前面一行加上至少三个连续~符号, 在结尾后面一行加同样数目的~符号。 这样的代码段前后也必须空行以与其它内容分开。 另外,如果代码内本身含有~行, 只要使得开头与结尾标志中的~个数更多就可以了。 例如下面的输入
~~~
#include <math.h>
double sqr(double x){
return(x*x);
}
~~~
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
使用栅栏式代码段时可以在开始行尾写大括号, 在大括号内写选项。 其中一种选项是要求按照某种编程语言对结果进行彩色语法显示, 如.cpp表示C++,.c表示C,.r表示R,.python表示python等。 选项.numberLines要求该代码行编号, 选项startFrom=指定开始行号。如 如:
~~~{.cpp .numberLines startFrom=101}
#include <math.h>
double sqr(double x){
return(x*x);
}
~~~
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
21.3.8 链接
最简单的链接是原样显示的可点击的链接, 只要把链接地址用小于号和大于号包在中间, 两边用空格和其它内容隔开。 如果是网页,需要加http://, 如果是邮箱,需要加mailto:。 例如,如下代码:
北京大学的网页地址是: <http://www.pku.edu.cn/> 。
显示为
北京大学的网页地址是: http://www.pku.edu.cn/ 。
除此之外, Markdown 还支持两种形式的链接语法: 行内式和引用式两种形式。 不管是哪一种,链接的显示文字都是用方括号[...]来标记。
要建立一个行内式的链接, 只要在方括号内写链接的显示文字, 右方括号后面紧接着圆括号, 并在圆括号中间插入网址链接即可。 方括号部分与圆括号部分之间不能断开。 例如:
请参考:[李东风的教学主页](http://www.math.pku.edu.cn/teachers/lidf/course/index.htm)
变成了
请参考:李东风的教学主页
在圆括号中,链接后面还可以包含用双撇号包围的标题文字, 与链接之间用空格分开。
引用式的链接, 需要在某处(比如文章结尾)定义一些链接的标识符, 然后用方括号包围链接的显示文字, 后面紧接着方括号包围着链接的标识符。
为了定义链接标识符, 用方括号包围链接标识符, 前面可以有至多3个空格缩进, 右方括号后面紧接着冒号和一个空格, 空格后写链接地址, 然后空格,在两个双撇号中间写一个链接地址的标题。 例如
[baidu]: http://baidu.com/ "百度"
[pku]: http://www.pku.edu.cn/ "北大"
这时,在文章中就可以用标识符调用链接, 如[北京大学主页][pku]将变成链接北京大学主页。
使用引用式的链接, 有些像论文中把所有参考文献排列在文章末尾, 文中用到某一篇文献只要提及其序号。
还有一种链接是内部链接,用于文内跳转。 在各级标题行的末尾, 可以添加{#自定义标签}这样的内容, 其中"自定义标签"是自己写的一个标识符, 标识符仅使用英文字母、数字、下划线、减号, 用来区分不同的位置。 比如,本文第一节"介绍"添加了markdown-intro为标签, 就可以用"[回到介绍](#markdown-intro)"产生链接 回到介绍。
21.3.9 插入图形
图形只能用链接形式, 不可能保存到一个纯文本文件内。 图形文件可以存在于远程服务器上, 也可以是与生成的HTML文件在同一目录结构中的文件。 语法仍使用行内式和参考式两种形式。 转化成HTML、PDF、Word格式后可以把图形内嵌在输出文件内部。
行内式的图片链接, 是普通行内链接格式前面添加了一个叹号, 惊叹后面紧接着方括号, 方括号内写图片的标题,标题可以空缺, 在右方括号后面紧接着圆括号, 圆括号内写图片的链接。
例如,下面的代码可以插入百度的一个logo,使用的是网上的资源:

结果为

为了插入保存在本地的与Markdown源文件在同一子目录或下级子目录的图形, 只要在圆括号中写图片文件名(如果与Markdown源文件在同一子目录)或相对路径。 例如,在D:\work\figs下的图形文件baidu_logo.gif在本Markdown源文件所在目录的figs子目录中, 可以用代码

结果为

这样含有网上图片和本地图片的Markdown源文件转化为HTML和docx格式, 都可以正常显示插入的图片。
与链接类似, 也可以在文章某处(比如末尾)定义图片的标识符, 然后把行内图片引用中图片地址替换成图片标识符即可。
21.3.10 表格
Markdown文本格式的表格就像是用减号、等号、竖线画的文本格式表格一样, 转化为HTML、docx等格式后就变成了富文本的表格。 有如下几种表格:
- 管道表
- 简单表
- 换行表
- 有格表
21.3.10.1 管道表
管道表在两列之间用竖线分开, 在列标题下面用减号画横线, 用如下方法指定各对齐方式:
- 在列标题下的横线开始加冒号,表示左对齐;
- 在列标题下的横线末尾加冒号,表示右对齐;
- 在列标题下的横线两端加冒号,表示居中对齐;
- 列标题下面仅有横线没有冒号,表示缺省对齐方式,一般是左对齐。
在表格内容后面空一行后写用Table:开头的表格说明。
这种方法不需要输入内容上下对齐,适用于中文内容。 后面所讲的简单表、换行表、有格表需要能够输入内容对齐, 对于中英文混合内容很难做到对齐, 所以仅管道表比较适合中文内容。
例如:
| 姓名 | 收入 | 职业 | 颜色偏好 |
|:------|-----------:|:---------------:|-----------|
| 赵四海 | 123456 | 业务经理 | 红 |
| 刘英 | 50 | 无 | 蓝 |
| 钱德里 | 3200 | 保洁 | 灰 |
Table: 管道表示例
结果为
| 姓名 | 收入 | 职业 | 颜色偏好 |
|---|---|---|---|
| 赵四海 | 123456 | 业务经理 | 红 |
| 刘英 | 50 | 无 | 蓝 |
| 钱德里 | 3200 | 保洁 | 灰 |
管道表不允许输入单元格换行, 单元格内容太宽时转换结果可能自动换行, 自动换行时列宽度与输入的列标题下横线宽度成比例。
21.3.10.2 简单表
简单表的格式是, 第一行是各列标题, 第二行是各标题下面用减号组成的表格线, 同一行的不同列要用空格分开, 从第三行开始是内容。
在表格前或表格后用空行隔开的以Table:开头的行是表格说明或标题。
为了确定表格每列单元格内容如何对齐, 用列标题下的表格线给出提示:
- 表格线与列标题右对齐,表示该列右对齐;
- 表格线与列标题左对齐,表示该列左对齐;
- 列标题在表格线中间,表示该列居中对齐;
- 列标题左右都与表格线对齐,表示该列为缺省对齐方式,一般是左对齐。
一定要使用一个等宽字体来编辑这样的表格,否则对齐与否无法准确分辨。 单元格内容不能超出表格线左端。 经过试验发现, 中文内容很难按这种方法对齐。
例如:
Name Income Job Color
------ -------- ------------------ -----
Jane 123456 Research Assistant red
John 50 N/A blue
William 3200 Cleaner blue
Table: 一个简单表的例子
结果为:
| Name | Income | Job | Color |
|---|---|---|---|
| Jane | 123456 | Research Assistant | red |
| John | 50 | N/A | blue |
| William | 3200 | Cleaner | blue |
21.3.10.3 换行表
换行表在输入列标题和单元格内容时, 允许输入内容拆分行,但是转化后并不拆分行。 这样的表以一行减号开始,以一行减号结束, 中间的表格用空行分开实际的不同行。 例如:
----------------------------------------------------
Name
of
Subject Income Job color
------ -------- ------------------ -----
Jane 123456 Research red
Ayer Assistant
John 50 N/A blue
Tukey
William 3200 Cleaner blue
Tale
----------------------------------------------------
Table: 一个换行表的例子
结果为:
| Name of Subject | Income | Job | color |
|---|---|---|---|
| Jane Ayer | 123456 | Research Assistant | red |
| John Tukey | 50 | N/A | blue |
| William Tale | 3200 | Cleaner | blue |
换行表输入时各列的输入宽度是有作用的, 输入较宽的列结果也较宽。
21.3.10.4 有格表
完全用减号、竖线、等于号、加号画出表格线。 这样的表在文本格式下呈现出很好的表格形状。 转化后不能指定对齐方式。
例如:
Table: 有格表示例
+---------------+---------------+--------------------+
| Fruit | Price | Advantages |
+===============+===============+====================+
| Bananas | $1.34 | - built-in wrapper |
| | | - bright color |
+---------------+---------------+--------------------+
| Oranges | $2.10 | - cures scurvy |
| | | - tasty |
+---------------+---------------+--------------------+
结果为
| Fruit | Price | Advantages |
|---|---|---|
| Bananas | $1.34 | built-in wrapperbright color |
| Oranges | $2.10 | cures scurvytasty |
21.4 附录:pandoc软件介绍
pandoc是一个杰出的开源软件, 作者为John MacFarlane。 RStudio软件中已经包含了这个软件。 软件在命令行运行, 可以用来在多种不同的文件格式之间进行转换, 输入格式一般是文本格式, 比如markdown、LaTeX、MediaWiki、reStructured Text、 HTML、DocBook, 但是也可以输入MS Word docx、Open Office ODT、EPUB格式。 输出可以是这些文本格式, 也可以是MS Word docx、Open Office ODT、EPUB、LaTeX等格式, 在安装了LaTeX编译系统如MikTeX时可以输出为PDF。 RStudio软件中包括了一份pandoc软件程序。
可以用普通文本编辑器编写markdown格式的文件, 用pandoc转换为HTML或MS Word docx等格式。 因为pandoc需要UTF8编码的输入文件, 所以应该把markdown文件保存为UTF格式, MS Windows下的Notepad++软件可以很容易地编辑文本文件 并在各种编码之间转换。 实际上,MS Windows下有一个markdown编辑程序Smarks就是基于pandoc软件的。
首先, 从pandoc网站下载并安装pandoc。 安装程序很奇怪地安装到了 C:\Users\登录用户名\AppData\Local\Pandoc中, 请将此子目录复制到一个合适的位置, 比如C:\Pandoc。 如果把此路径加入到Windows系统的可执行文件搜索路径中 (在"控制面板-系统和安全-系统-高级系统设置-环境变量"中, 为系统变量的Path添加一个分号分开的路径C:\Pandoc即可以不用全路径访问 pandoc.exe可执行文件。
为了用pandoc转化某个markdown文件, 首先在该文件所在子目录打开一个Windows命令行窗口, 在MS Win10系统中只要在文件管理器的"文件"菜单选择 "打开命令提示符"即可。 比如,文件名是test.md, 用如下pandoc命令可以转换为.docx文件(MS Word文件的新版本):
C:\Pandoc\pandoc -o test.docx test.md
用如下pandoc命令可以转换为.html文件:
C:\Pandoc\pandoc -s -o --mathjax test.html test.md
如果把pandoc.exe加入了Windows操作系统的Path环境变量中, 上面的 C:\Pandoc\pandoc 可以简写为 pandoc。
pandoc在其它操作系统中也有相应的版本。 软件下载与文档见Pandoc的网站http://pandoc.org。
如果使用RStudio编辑markdown文件或者R Markdown文件, 它会自动调用内置的pandoc程序。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
22 R Markdown文件格式
22.1 R Markdown文件
借助于R的knitr和rmarkdown扩展包的帮助, 可以在Markdown格式的源文件中插入R代码, 使得R代码的结果能够自动插入到最后生成的研究报告中。 这种格式称为R Markdown格式,简称为Rmd格式, 相应的源文件扩展名为.Rmd。 输出格式可以是HTML、docx、pdf、beamer等。 R Markdown的基础格式是markdown格式, 严格说来是Pandoc软件支持的增强版的markdown格式, 比如, 支持LaTex格式的数学公式, 支持各种编程语言语法彩色加亮显示,等等。
knitr的详细文档参见网站knitr文档。 关于R Markdown可参考专著(Xie, Allaire, and Grolemund 2019)。 RStudio网站提供了一个R Markdown使用摘要下载: (rmarkdown-2.0.pdf)[rmarkdown-2.0.pdf]。 Pandoc的文档见pandoc网站。
一个Rmd文件中包含元数据(metadata)、正文内容和R代码三种成分, 比如,下面是一个简单的Rmd文件样例:
---
title: "R语言简介"
author: "李东风"
date: "2019-08-29"
output: html_document
---
这里是正文段落。
段落中仍可以利用一般的Markdown语法,
比如在两边用双星号表示**粗体加重**,
在用两边反单撇号表示代码,如`y <- sin(x)`。
下面是一个R代码段,有文字输出:
```{r}
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
```
下面是一个R代码段,有图形输出:
```{r}
plot(x)
```
下面是一个R代码段,
有富文本表格输出:
```{r}
knitr::kable(as.data.frame(x))
```
在文字段落内部也可以有代码,
比如,x的第一个元素值为`r x[1]`。
```
在文件开头用三个减号组成的行包围的内容称为元数据 , 可以用来规定文章标题、作者、日期、输出格式、输出设置等属性。 见22.11。
22.2 R Markdown文件的编译
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。 用快捷图标Knit可以将文件转换成HTML格式、PDF格式(需要安装LaTeX编译软件)、MS Word格式。
从HTML格式可以转换成PDF格式。 为此, 安装Google的Chrome浏览器, 在Chrome中打开HTML文件后, 从Chrome浏览器的菜单中找到打印菜单, 从中选择打印机为"保存到PDF"选项, 就可以将HTML网页转换成PDF, 其中的数学公式、表格、图形都可以比较好地转换。 但是,经试验,slidy幻灯片用Internet Explorer浏览器转换PDF更合适。 其它浏览器在转换数学公式时容易将公式右侧的编号裁切掉。
从Word文件也可以转换成PDF格式, 用MS Word软件的"文件-导出"或者"文件-另存为"功能即可。
如果想将R Markdown文件借助于LaTeX格式转换为PDF, 需要在系统中安装一个TeX编译器, 如MS Windows下有MikTeX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包。
如果不借助于RStudio软件, 可以用R软件、knitr包、rmarkdown包、pandoc软件来完成R Markdown源文件的编译。 比如,假设test.Rmd是一个这样的R Markdown格式的文件, 注意一定要使用UTF-8编码保存, 可以在R或RStudio中运行如下命令以生成含有运行结果的html文件:
rmarkdown::render("myfile.Rmd", output_format = "html_document", encoding="UTF-8")
其中myfile.Rmd是源文件, 产生的HTML文件带有图形、支持数学公式。
在R或RStudio中可以用如下命令把.Rmd文件转化为MS Word docx格式:
rmarkdown::render("myfile.Rmd", output_format = "word_document", encoding="UTF-8")
使用RStudio软件使得这些任务可以一键完成, 而且有很好的数学公式支持, 所以建议编辑R Markdown文件还是使用RStudio软件。
用RStudio的Knit图标一键编译与用rmarkdown::render()命令编译有一个重要差别:
- 用Knit图标编译,Rmd文件中的程序会在一个崭新的会话中执行, 当前会话中已经定义的函数、变量、导入的扩展包不会影响到编译结果;
- 用
rmarkdown::render()编译, Rmd文件中的程序是在当前会话中执行的, 会带来一定的兼容性问题, 有可能在别人的环境下就不能正确执行或者会给出不同结果。 但是,rmarkdown::render()可以通过程序调用, 比如,循环地从同一个Rmd生成一系列不同的报告。 为了不让当前会话环境干扰结果, 可以人为地打开一个新会话。
22.3 在R Markdown文件中插入R代码
插入的R代码分为行内代码与代码块。
行内代码的结果插入到一个段落中间, 代码以``r开头,以```结尾, 如r sin(pi/2)`在结果中会显示为1。 为了原样显示一个反向单撇号, 可以在两边用双反向单撇号界定并用空格隔开内部的内容。
代码块则把结果当作单独的段落, 按照Markdown格式的规定, 代码块的前后需要有空行, 但是R Markdown实际上放松了这个要求, 允许前后不空行。 R代码段以单独的一行开头, 此行以三个反单撇号开始, 然后是{r},如````{r}`。 代码段以占据单独一行的三个反单撇号`````结尾。 如
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
结果将变成
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
## [1] -0.63 0.18 -0.84 1.60 0.33 -0.82 0.49 0.74 0.58 -0.31
可以看出,代码段程序会被插入到最终结果中, 代码段的文本型输出会插入到程序的后面。
代码块也可以嵌入到引用、列表等环境中。
代码块中作的图将自动插入到当前位置。 下面的程序:
plot(x)
结果将显示为:
plot(x)

在RStudio中, 可以用Insert快捷图标插入代码段, 还可以用Ctrl+Alt+I快捷键插入代码段。
22.4 输出表格
knitr包提供了一个 kable() 函数可以用来把数据框或矩阵转化成有格式的表格, 支持HTML、docx、LaTeX等格式。
例如,计算线性回归后, summary()函数的输出中有coefficients一项,是一个矩阵, 如果直接文本显示比较难看:
x <- 1:10; y <- x^2; lmr <- lm(y ~ x)
co <- summary(lmr)$coefficients
print(co)
## 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函数来显示:
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 |
kable()函数的digits=选项可以控制小数点后数字位数, caption=选项可以指定表的标题内容。
R扩展包xtable提供了一个xtable()函数, 也可以用来生成HTML格式和LaTeX格式的表格, 但是需要指定要输出的格式。 xtable对比较多的R数据类型和输出类型提供了表格式显示功能, 包括矩阵、数据框、回归分析结果、方差分析结果、主成分分析结果、 若干分析结果的summary结果等。 例如,上面的回归结果用xtable()函数显示如:
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的结果不可用。
R扩展包pander提供了更好的表格能力, 也能与knitr包很好的合作输出。 其pander()函数可以将多种R输出格式转换成knitr需要的表格形式。 如
pander::pander(lmr)
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | -22 | 5.55 | -3.964 | 0.004153 |
| x | 11 | 0.8944 | 12.3 | 1.778e-06 |
但是,经过试验发现, 表中中有中文时pander包会出错。
22.5 利用R程序插图
Rmd文件的插图有两种, 一种是已经保存为图形文件的, 主要是png和pdf图片; 另一种是文中的R代码生成的图形。
已经有图形文件的, 可以用markdown格式原来的插图方法, 见markdown格式介绍。 但是,这样做不能给图形自动编号, 另外因为制作图书是有网页和PDF书两种主要输出格式的, 原有的插图方式在这两种输出格式上有细微的不一致。 所以,最好是统一使用Rmd的插图方法。
Rmd的插图方法就是写一段R代码段来插图, 如果是用程序作图,则代码中写作图的代码; 如果是已有的图形文件, 可以在一个单独的R代码段中用类似下面的命令插图:
```{r, echo=FALSE}
knitr::include_graphics("figs/myfig01.png")
```
knitr::include_graphics("figs/myfig01.png")
其中figs是存放图形文件的子目录名, myfig01.png是要插入的图形文件名。 这样, 如果同时还有myfig01.pdf的话, 则HTML输出使用png图片而PDF输出自动选用pdf文件。 另外, 插图的选项在代码段的选项中规定: 用代码段的fig.with和fig.height选项指定作图的宽和高(英寸), 用out.width和out.height选项指定在输出中实际显示的宽和高, 实际显示的宽和高如果使用如"90%"这样的百分数单位则可以自动适应输出的大小。
由于PDF中的中文编码不能自动识别, 所以在每个Rmd源文件的开头应该加上如下的设置, 使得生成PDF图时中文能够正确显示:
```{r setup-pdf, include=FALSE}
pdf.options(family="GB1")
```
其中include=FALSE表示要不显示代码段的代码, 有运行结果也不插入到输出结果中, 是否运行视缺省的eval=的值而定。
22.6 代码段选项
独立代码段以````{r}开头, 在大括号内还可以写一些选项, 选项之间以及与开始的r之间用逗号分隔, 所有选项写在同一行内不要换行。 选项都使用"选项名=选项值"的格式, 选项值除了使用常量外也可以使用全局变量名或表达式。 在大括号内开头的 r`空格后写一个由英文大小写字母、数字、减号组成的标识符, 作为代码段的标签。 标签中不要用其它类型的字符, 下划线也不要用。 如
```{r firstCode}
cat('This is 第一段, 有标签.\n')
```
关于代码段选项, 详见https://yihui.name/knitr/options。
22.6.1 代码和文本输出结果格式
R代码块和R代码块的运行结果通常是代码块原样输出, 运行结果用井号保护起来, 这样有利于从文章中复制粘贴代码。 如:
```{r}
s <- 0
for(x in 1:5) s <- s + x^x
s
```
结果为:
s <- 0
for(x in 1:5) s <- s + x^x
s
## [1] 3413
22.6.1.1 highlight选项
转化后的R代码块缺省显示为彩色加亮形式。 用选项highlight=FALSE关闭彩色加亮功能。
22.6.1.2 prompt和comment选项
如果希望代码用R的大于号提示符开始, 用选项prompt=TRUE。 如果希望结果不用井号保护, 使用选项comment=''。 例如:
```{r prompt=TRUE, comment=''}
sum(1:5)
```
结果为:
> sum(1:5)
[1] 15
22.6.1.3 echo选项
如果希望不显示代码, 加选项echo=FALSE。 如
```{r echo=FALSE}
print(1:5)
```
结果为:
## [1] 1 2 3 4 5
22.6.1.4 tidy选项
加选项tidy=TRUE可以自动重新排列代码段, 使得代码段格式更符合规范。例如:
```{r tidy=TRUE}
s <- 0
for(x in 1:5) {s <- s + x^x; print(s)}
```
结果为:
s <- 0
for (x in 1:5) {
s <- s + x^x
print(s)
}
## [1] 1
## [1] 5
## [1] 32
## [1] 288
## [1] 3413
22.6.1.5 eval选项和include选项
加选项eval=FALSE, 可以使得代码仅显示而不实际运行。 这样的代码段如果有标签, 可以在后续代码段中被引用。
加选项include=FALSE, 则本代码段仅运行, 但是代码和结果都不写入到生成的文档中。
22.6.1.6 child选项
加选项child='文件名.Rmd'可以调入另一个.Rmd文件的内容。 如果有多个.Rmd文件依赖于相同的代码,可以用这样的方法。
22.6.1.7 collapse选项
一个代码块的代码、输出通常被分解为多个原样文本块中, 如果一个代码块希望所有的代码、输出都写到同一个原样文本块中, 加选项collapse=TRUE。 例如, 没有这个选项时:
```{r}
sin(pi/2)
cos(pi/2)
```
结果为:
sin(pi/2)
## [1] 1
cos(pi/2)
## [1] 6.123032e-17
代码和结果被分成了4个原样文本块。 加上collapse=TRUE后,结果为:
sin(pi/2)
## [1] 1
cos(pi/2)
## [1] 6.123032e-17
代码和结果都在一个原样文本块中。
22.6.1.8 results选项
用选项results=选择文本型结果的类型。 取值有:
markup, 这是缺省选项, 会把文本型结果变成HTML的原样文本格式。hide, 运行了代码后不显示运行结果。hold, 一个代码块所有的代码都显示完, 才显示所有的结果。asis, 文本型输出直接进入到HTML文件中, 这需要R代码直接生成HTML标签, knitr包的kable()函数可以把数据框转换为HTML代码的表格。
例如:results='hold'的示例:
```{r collapse=TRUE, results='hold'}
sin(pi/2)
cos(pi/2)
```
结果为:
sin(pi/2)
cos(pi/2)
## [1] 1
## [1] 6.123032e-17
22.6.1.9 错误信息选项
选项warning=FALSE使得代码段的警告信息不进入编译结果, 而是在控制台(console)中显示。 有一些扩展包的载入警告可以用这种办法屏蔽。
选项error=FALSE可以使得错误信息不进入编译结果, 而是出错停止并将错误信息在控制台中显示。
选项message=FALSE可以使得message级别的信息不进入编译结果, 而是在控制台中显示。
22.6.2 图形选项
22.6.2.1 图形大小
用fig.width=指定生成的图形的宽度, 用fig.height=指定生成的图形的高度, 单位是英寸(1英寸等于2.54厘米)。
下面给出一个长宽都是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)

fig.width=和fig.height=规定的是生成的图形大小, 实际生成图形的显示大小会受到dpi(分辨率)影响, 默认dpi是72(每英寸72个点), 也可以用dpi=选择分辨率。 转化后的HTML文件显示时不一定按原始大小显示。 用out.width=和out.height=可以指定显示大小, 但是必须是最终文件格式承认的单位, 比如HTML的图形大小单位是点(平常说屏幕分辨率的单位)。 或者写成如90%这样的百分比格式。 例如在上面的例子中加上输出度为页面宽度80%的选项:
```{r fig.width=10/2.54, fig.height=10/2.54, out.width="80%"}
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)

当输出结果为HTML结果或者LaTeX转换的PDF时, 只要两个图形的总宽度小于页面宽度, 两个连续的图形就可以左右并列放置。 Word不支持这种功能。 例如:
```{r, echo=FALSE, fig.width=10/2.54, fig.height=10/2.54, out.width="45%"}
curve(exp(-0.1*x)*sin(x), 0, 2*pi)
abline(h=0, lty=3)
curve(exp(-0.1*x)*cos(x), 0, 2*pi)
abline(h=0, lty=3)
```
结果为


22.6.2.2 图形结果选择
用fig.keep=选项可以选择保留哪些R代码生成的图。 缺省是fig.keep='high', 即保留每个高级图形函数的结果图形, 低级图形函数对高级图形函数的更改不单独保存而汇总到高级图形函数结果中。 如
par(mar = c(3, 3, 0.1, 0.1))
plot(1:10, ann = FALSE, las = 1)
text(5, 9, "Testing low level graphics")

其中text()函数的结果与高级图形函数plot()的结果一起显示。
fig.keep还可以取:all, 会把低级图形函数修改后的结果单独保存; last, 仅保留最后一个图形;first, 仅保留第一个图; none, 所有图都不显示出来。
22.6.3 缓存(cache)选项
当R Markdown文章比较长,包含的R代码比较多, 或者代码段运行需要比较长时间时, 反复编译整篇文章会造成不必要的计算, 因为有些代码段并没有修改, 依赖的数据也没有改变。 knitr提供了缓存功能, 代码段选项cache=TRUE对代码段打开缓存, 允许暂存上次运行的结果(包括文本结果和图形) 而不需要重复运行代码段。 当代码段被修改时, 缓存被放弃, 编译时重新运行代码段。
缓存这种功能需要慎重使用, 免得错误地使用了旧的结果。 当后面的代码段需要使用前面代码段结果时, 如果前面结果改了, 后面的代码段就不能使用缓存的结果而必须重新计算。 为此, 在后面的代码段中应该加上dependson=选项, 比如dependson=c('codeA', 'codeB'), 其中codeA和codeB是前面的缓存了的代码段的标签, 其结果会用在本代码段中。 也可以使用代码段选项autodep=TRUE, knitr试图自动确定前后代码段之间的依赖关系, 每当前面的代码段改变时, 后面的用到其结果代码段也自动重新计算而不使用缓存的旧结果。
建议仅对计算一次需要较长时间的代码段使用缓存功能, 后面依赖于其结果的代码一定要加上dependson=选项。 建议代码段尽可能有标签,这样在编译失败时能马上看出失败的地点。
为了保险起见, 可以尽量不使用缓存功能, 而是用save()功能将需要长时间结算的结果保存下来, 用load()载入然后输出到结果文档中。
22.7 章节目录链接问题
对于英文文件, R Markdown基于的pandoc软件可以自动从标题生成适当的链接标签, 将HTML输出或者PDF输出设置属性toc: true后可以生成可点击的章节目录。 但是,目前Pandoc对于中文文件的支持差一些, 所以中文文件要自动生成可点击的目录, 需要在每个标题行的末尾,空格后添加{#label}, 其中label是自己指定的标签内容, 但是建议仅使用英文字母、数字、减号。 如
### 第三章第一节标题 {#c3-s1-int}
如果希望某个标题不参与自动编号, 可以在标题末尾空格之后加上{-}标记。
22.8 数学公式
22.8.1 在Markdown中输入数学公式
原始的Markdown格式并不支持数学公式。 Pandoc扩展的markdown格式提供了对数学公式的支持, 可以在Markdown文件中插入LaTeX格式的数学公式。 虽然不能提供所有的LaTeX公式能力, 但是常用的数学公式还是能做得很好, 转换到HTML、docx都可以得到正常显示的公式。
用RStudio软件编译Markdown文件,可以在其中插入LaTeX格式的数学公式, 编译成HTML或者docx格式后都可以正常显示数学公式, 在另外安装的LaTeX编译器的支持下也可以将.Rmd格式编译LaTeX格式然后再转换为PDF格式, 这种方法对数学公式的支持会更完善。
关于数学公式的软件设置参见下面设置部分的内容。
22.8.2 数学公式类别
数学公式公式分为行内公式和独立公式。 行内公式和段落的文字混排, 写在两个美元符号$中间,或者\(和\)之间。 例如$f(x)=\frac{1}{2} \int_0^1 \sin^2 (t x) dt$变成 。 开头的$后面不能紧跟着空格, 结尾的$不能紧跟在空格后面。
独立公式写在成对的美元符号中间,或者\[和\]之间。 例如:
$$
f(x) = \frac{1}{2} \sum_{j=1}^\infty \int_0^1 \sin^2(j t x) dt .
$$
显示为
22.8.3 基本功能
在数学公式中, 用下划线表示下标, 比如$x_1$结果为。 用^表示上标, 如$x^2$结果为。 上下标都有,如$x_1^2$结果为。
公式中用大括号表示一个整体, 比如$x^(1)$不能得到, 需要用$x^{(1)}$。
公式中用反斜杠开始一个命令, 命令仅包含字母而不能包含数字, 数字只能作为参数。 如$\frac{1}{2}$和$\frac12$都可以生成。 类似的命令如$\sqrt{2}$为。
希腊字母都有对应的命令, 如$\alpha$为, $\Sigma$为。
常用数学函数有自己的命令, 如$\sin x$变成, $\exp (x)$为。
圆括号与方括号可以直接使用, 绝对值符号用|, 如$|x|$变成。 但是,大括号必须写成\{和\}的形式, 如$\exp\{-\frac12 x^2\}$变成。
为了使得括号能够与括号内部的内容等高, 可以用\left和\right命令进行修饰, 如
$$
\phi(x) = \frac{1}{\sqrt{2\pi}} \exp\left\{ \frac{1}{2} x^2 \right\}
$$
变成
注意\left``\right
求和如$\sum_{i=1}^n x_i$变成。 乘积如$\prod_{i=1}^n x_i$变成。 积分如$\int_0^1 f(x) dx$变成。
22.8.4 修饰符
$f'(x)$显示为, 表示导数; $f''(x)$显示为, 表示二阶导数。 顺便说一句, 偏导数写法如$\frac{\partial f(x,t)}{\partial x}$, 显示为。
的写法是$\bar{x}$。 的写法是$\overline{\text{span}}$。 的写法是$\hat{x}$。 的写法是$\tilde{x}$。 的写法是$\vec{x}$。
22.8.5 对齐与矩阵
为了产生对齐的公式, 在独立公式中使用aligned环境。 公式中的环境以\begin{环境名}开始, 以\end{环境名}结束, 用\\表示换行,用&表示一个上下对齐位置。 如
$$
\begin{aligned}
f(x) =& \sum_{k=0}^\infty \frac{1}{k!} x^k \\
=& e^x
\end{aligned}
$$
转化成
可以用pmatrix环境制作写在圆括号中的矩阵, 用bmatrix环境制作写在方括号中的矩阵, 用vmatrix制作写在绝对值号中的矩阵,如
列向量、行向量也可以用这种办法制作。
22.8.6 特殊字体
数学公式中的单词、文字必须用\text{...}保护,比如
$$
\text{CV} = \frac{S}{\bar x} \times 100 \%
$$
变成
上例中如果不用\text{}
有时用粗体表示向量或者矩阵, 用\boldsymbol{...}说明。如
$$
\boldsymbol{v} = (v_1, v_2)^T
$$
变成
美术体英文字母用\mathcal{...}, 如写法为$\mathcal{A, B, C}$。
手写花体字母用\mathscr{...}, 如写法为$\mathscr{B, C, F, G}$。
22.9 其它编程语言引擎
Rmd文件中除了R代码段以外, 还可以插入Rcpp、Python、Julia、SQL等许多编程语言的代码段, 常用编程语言还可以与R代码段进行信息交换。
22.10 交互内容
在Rmd生成HTML结果时, 可以在结果中包含允许读者交互操作的内容, 比如, 用户修改模型参数, 使得模型报表、图形交互地改变。 有两种方法可以实现交互:
- HTML小程序(widgets), 由R扩展包htmlwidgets实现, 利用JavaScript函数库进行交互。 在这一功能基础上有一些派生的扩展包, 如DT,leaflet, dygraph。
- 利用shiny框架,这也是一个R扩展包, 交互功能由R的一个会话驱动。 Rmd文件的YAML元数据中需要设置
runtime: shiny。
22.11 属性设置
22.11.1 YAML元数据
可以在RStudio软件中编辑markdown文件与Rmarkdown文件, RStudio的markdown支持来自knitr、rmarkdown、bookdown扩展包和pandoc软件, .Rmd文件支持一些特殊的文件设置, 这些设置写在markdown文件和.Rmd文件的开头位置, 用三个减号组成的行作为开始标记与结束标记, 称为YAML元数据块(YAML meta data block), 块后面必须用空行分隔。 元数据块中可以用"设置属性名: 设置属性值"的办法设置属性, 用缩进表示属性内容,用上下对齐的行表示多项列表。 常用属性有title(标题)、author(作者)、date(日期)、output_format(输出格式)等,如
---
title: "临时测试"
author: "李东风"
date: "2016年7月6日"
---
这三个设置会出现在转换后结果的标题部分。 RStudio的中文支持还是有时出现问题, 如果出现涉及到YAML的错误, 先将中文内容替换为英文试一试。
因为冒号:在属性设置中有特殊意义, 属性设置值如果含有冒号, 需要把整个属性值两边用单撇号界定。
属性值可以是列表或多项,例如:
---
title: 'This is the title: it contains a colon'
author:
- name: Author One
affiliation: University of Somewhere
- name: Author Two
affiliation: University of Nowhere
tags: [nothing, nothingness]
abstract: |
This is the abstract.
It consists of two paragraphs.
---
此例中有title、author、tags、abstract四个属性。 author属性包含两个作者, 每个作者又有name和affiliation两个属性。 tags属性是一个两项的列表。 abstract属性用管道符号|表示开头,不需要结束标志,内容缩进。
22.11.2 输出格式
.Rmd文件开头的YAML元数据中, 属性output选择输出的格式, 如
html_document是HTML输出;pdf_document是PDF输出,通过系统中另外安装LaTeX编译系统转换;word_document是docx格式的Word文件输出,等等。
输出格式指定如:
output:
html_document: default
word_document: default
pdf_document: default
其中default表示该输出格式完全使用默认设置。 在输出格式没有定制设置时必须有default指定。
22.11.3 输出格式设置
在每种输出格式后面还可以继续添加该输出特有属性。 如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
pdf_document:
toc: true
22.11.4 目录设置
输出格式的toc: true选项指定自动生成目录, HTML输出、PDF输出、Word输出都支持此功能。 见上例。
output:
html_document:
toc: true
toc_depth: 2
上例中,html_document是output的属性, 隶属关系用缩进表示; html_document又有自己的属性toc和toc_depth, 隶属关系用缩进表示。 属性toc: true表示要自动生成可点击的目录。 输出格式的属性toc_depth是目录包含的章节层级数。
对html_document输出, 属性toc_float: true使得生成的文档在左侧显示一个目录导览窗格。 而toc_float属性又可以指定一些属性,隶属关系用缩进表示。 toc_float的属性collapse: true表示仅展开章节第一层级, smooth_scroll: true使得通过导览窗格跳跃时页面有平滑滚动过程显示。 用如:
output:
html_document:
toc: true
toc_float:
collapse: true
smooth_scroll: true
22.11.5 章节自动编号
输出格式的属性number_sections为true可以自动对章节编号。 HTML输出与PDF输出都支持此功能。
在章节自动编号时, 如果不是利用bookdown包而是基于基本的R Markdown, 文中的分节最高层级最好用一个井号, 对应于节, 如果用两个井号, 编号会变成0.1,0.2这样。
22.11.6 Word输出章节自动编号及模板功能
Word文件不能自动编号, 解决办法是生成适当的模板文件, 如wordstyle.docx, 然后在Rmd文件的元数据部分为word_document输出增加reference_docx选项,如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
reference_docx: wordstyle.docx
这样,新编译的Rmd文件就可以采用wordstyle.docx的格式设置, 比如章节自动编号等。 目前目录标题还是英文, 需要在结果中人为地修改为中文。 一个样例模板下载如下: wordstyle.docx
22.11.7 HTML特有输出格式设置
对于html_document输出类型, 可以用theme属性设置一个主题, 取值如default, cerulean, journal, flatly, darkly, readable, spacelab, united, cosmo, lumen, paper, sandstone, simplex, yeti。
用highlight属性设置程序语言语法高亮样式, 可取值有default, tango, pygments, kate, monochrome, espresso, zenburn, haddock, and textmate。 用null表示取消语法高亮。
可以用css属性指定一个自定义的CSS样式表文件。 如果希望完全用自己的样式代替原有样式, 可以设置theme: null。
code_folding属性设置HTML结果中代码折叠选项, 取值hide可以隐藏代码, 但读者通过选项可见。 取值show可以显示代码, 但读者通过选项可隐藏代码显示。
22.11.8 关于数学公式支持的设置
Rmd格式支持数学公式, 在生成的HTML、Word、PDF中都可以正常显示数学公式。
以HTML为输出时, 会使用MathJax库显示数学公式。 这是一个用于在浏览器中显示数学公式的Javascript程序库, 显示效果很好, 还支持多种显示实现方式, 支持包括LaTeX在内的多种数学公式输入方法。
MathJax库很大, 所以一般是从其网站按需远程调用的, 但是远程调用MathJax库在网络不畅通时会使得公式显示极为缓慢甚至无法显示, 所以Rmd允许将MathJax本地化。 在.Rmd文件头部YAML元数据的某种HTML输出格式的属性中, 设置属性mathjax: local和就可以使得MathJax库被放在生成的HTML的一个下层目录中。 设置如
output:
html_document:
toc: true
self_contained: false
mathjax: local
注意设置mathjax: local同时必须设置self_contained: false。 在不使用本地MathJax副本时, 可以设置self_contained: true, 这使得图形文件、JavaScript代码等依赖项也打包在生成的单一HTML文件中, 如果设为false, 这些依赖文件会存放在单独文件中。 可以用lib_dir属性指定一个子目录用来存放这些依赖文件, 多个Rmd文件可以共用同一个lib_dir值。
将MathJax用mathjax: local属性本地化有明显的缺点。 这时,每个Rmd项目都需要一个MathJax库副本, 使得文件备份变得很麻烦。 下面的设置方法可以令多个Rmd项目共享一个共同的本地MathJax库。
22.11.9 输出设置文件
如果一个项目包含多个.Rmd文件, 每个文件单独用YAML元数据进行设置比较繁琐, 修改时也很麻烦。 可以在项目目录中增加一个_output.yml文件, 其中包含所有.Rmd文件共用的output属性的设置, 各个.Rmd文件还可以有自己单独的output属性, .Rmd文件YAML元数据中的属性优先级高于共同设置的属性。
例如,_output.yml文件内容如下:
html_document:
toc: yes
number_sections: yes
mathjax: "../../MathJax/MathJax.js"
includes:
in_header: "_header.html"
word_document:
toc: yes
reference_docx: wordstyle.docx
pdf_document:
includes:
in_header: preamble.tex
latex_engine: xelatex
上面设置了使用本地硬盘的MathJax库, 位于项目目录的上两层目录中的MathJax子目录中。 这样可以使得多个项目共享一个MathJax库。 将生成的结果当作网站发布时, 只要将MathJax库也安装到项目在网站的目录的上两层的MathJax子目录中就可以。 其中_header.html内容如下,是关于MathJax具体的一些设置:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
jax: ["input/TeX","output/SVG"],
extensions: ["tex2jax.js","MathMenu.js","MathZoom.js"],
TeX: {
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
}
});
</script>
注意, _output.yml文件都是输出设置, 所以不能再有output属性,所以下面的_output.yml写法是不正确的:
output:
html_document:
toc: yes
22.12 LaTeX和PDF输出
Rmd文件的pdf_document输出类型是先转换为LaTeX文件, 再借助计算机系统中另外安装的LaTeX编译程序转换为PDF。 需要在系统中安装一个TeX编译器, MS Windows下有MikTeX软件包或者CTEX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包, 优点是直接用R命令就可以安装, 更新也由R自动进行,不需要用户干预。
许多LaTeX相关的YAML元数据不是设置在输出属性中, 而是设置为文件的顶级元数据。 如
其中属性fontsize和geometry都是LaTeX选项, 但是没有作为output--pdf_document的属性, 而是作为Rmd文件的顶级元数据属性。
用属性documentclass指定LaTeX文档类型, 比如article是论文格式, book是图书格式。 ctexart和ctexbook是适用于中文的格式。
fontsize是正文字体大小, 可取10pt, 11pt, 12pt, 其中10pt是缺省大小。
geometry用来指定geometry包的参数。
默认的LaTeX编译引擎是pdfLaTeX。 可以在pdf_document输出的属性中设置latex_engine: xelatex将引擎替换成xeLaTeX。 xeLaTeX的优点是支持UTF8编码,可以使用系统中现有字体, 而我们在写中文的R Markdown文档时必须使用UTF-8编码。
Rmd文件中的文献引用可以由pandoc软件执行, 但是在用LaTeX转换PDF时, 可以指定用一个LaTeX引用包, 如:
---
output:
pdf_document:
latex_engine: xelatex
citation_package: natbib
---
为了自动生成目录并自动为章节编号, 仍在pdf_document的属性中指定toc: true和number_section: true。
在使用bookdown管理Rmd文件时, 文献引用、目录、章节编号方式有另外的指定办法以及默认规则。
为了能够检查转换过程中的错误, 可以用pdf_document的属性keep_tex: true, 保留作为中间结果的.tex文件, 人工检查其中的错误。
可以在pdf_document输出的属性中指定若干个.tex文件插入到LaTeX文档的导言、正文最前面、正文最后后面,如
---
output:
pdf_document:
latex_engine: xelatex
keep_tex: true
citation_package: natbib
toc: true
number_sections: true
includes:
in_header: preamble.tex
before_body: doc-prefix.tex
after_body: doc-suffix.tex
---
preamble.tex主要用来载入额外的LaTeX包以及定义新的命令, 一个preamble.tex的例子如下
不支持百分号,只能去看原文档了。
http://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/index.html
22.13 生成期刊文章
节22.12的办法可以用来生成LaTeX然后转换为PDF, 可以用来撰写学位论文和期刊论文。 但是学位论文和期刊论文都有比较严格的格式要求, 用节22.12的一般方法需要对LaTeX比较熟悉才能达到格式要求。
用R扩展包rticles可以比较容易地将Rmd文件转换成期刊可接受的LaTeX和PDF格式。 见https://bookdown.org/yihui/rmarkdown/journals.html。 扩展包中对一些常见期刊提供了模板。
首先要安装rticles扩展包,命令为
install.packages("rticles")
为了生成新的论文源文件, 在RStudio中, 用"File -- New File -- R Markdown -- from Template"菜单, 从列出的文章模板中选一个。
杂志投稿的Rmd模板是用许多元数据来规定格式的。 用户可以修改其中的标题、作者、作者单位等信息。
因为rticlels的输出只有PDF, 所以必要时可以在Rmd源文件中直接使用LaTeX命令, 但如果Rmd本身可以完成时尽可能用Rmd的功能。
因为定理、图表自动标号和索引功能是由bookdown包提供的, 而rticles的输出类型实际是rmarkdown::pdf_docment, 所以可以联合使用bookdown与rticles,如
output:
bookdown::pdf_book
base_format: rticles::peerj_article
其中peerj_article可以替换成rticles提供的其它格式。
如果自己需要的模板rticles没有提供, 可以自己设法定义模板, 参见https://bookdown.org/yihui/rmarkdown/document-templates.html。
22.14 附录:经验与问题
22.14.1 Word模板制作
如果有合适的Word格式样例, 可以在YAML元数据的word_document的属性中, 设置reference_docs属性指向该模板文件。
为了制作Word模板, 不应该从头开始, 而是在没有模板的情况下从Rmd文件转换生成一个Word文件, 将其作为模板文件的基础进行修改。 在修改过程中, 应该制作过程的备份,以便修改错误时能退回上一个版本。
如果文章的大标题样式不是"标题", 将样式改为"标题"以免在后续的自动编号过程中参与编号。 修改的方法是选中大标题, 然后在Word软件主菜单的"开始--样式"选择框中选中"标题", 就可以设置其样式。
Word的目录是与"标题1"同级的, 这样会在自动编号时参与编号; 为此, 选中"Contents", 然后在主菜单的"开始--样式"选择框中, 找到突出显示的"TOC标题", 右键单击"修改", 在弹出的对话框中将"样式基准"从"标题1"改为"标题", 并在同一对话框中将适当调整样式, 如字体类型、大小、颜色、是否居中。 改完后保存并保存一个副本。
如果需要修改"标题","作者","日期","标题1"等等的字体、大小、颜色、对齐方式, 可以选中该部分,并在"样式"中邮件单击相应的样式,选择"修改"进行修改, 保存样式文件并试验Rmd文件是否正确地利用了修改的样式。
为了实现自动编号, 先在正文中选中一个一级标题(不能是目录标题), 从Word的主菜单栏找到"开始------段落------多级列表------定义新的多级列表", 在打开的对话框中点击"更多"选项, 逐一地选择"单击要修改的级别", 将级别1、2、3等分别修改, 主要是修改"将级别链接到样式"使得"级别1"与"标题1"对应, "级别2"与"标题2"对应,等等。 注意这个修改要一次性完成, 不能保存了文件后再次定义新的多级列表。
修改模板文件的页边距也会使得利用其为模板的Rmd文件转换结果被修改。 为了修改模板文件的页边距, 在主菜单"布局------页边距------自定义页边距"弹出的对话框中修改。
生成的目录的标题内容是"Table of Contents", 目前只能对Rmd输出的docx文件直接修改, 修改模板文件的标题内容并不能使得Rmd输出被修改。
参考:Richard Layton的网站文章 https://rmarkdown.rstudio.com/articles_docx.html。
22.14.2 数学公式设置补充
如果不使用RStudio, R扩展包rmarkdown的markdownToHTML()函数可以把含有数学公式的内容转换成可显示公式的HTML文件, R扩展包knitr的knit2html()也可以实现此功能。 用rmarkdown扩展包的markdownToHTML()函数生成的含有数学公式的内容。
单独使用pandoc软件时, 也可以用普通文本编辑器在Markdown文件中输入LaTeX格式的数学公式, 然后用pandoc软件转化为带有数学公式的docx文件, 不需要额外选项。 但是,为了能够在转换的HTML文件中正常显示数学公式, 需要在运行Pandoc时增加运行选项--maxjax,如
pandoc --mathjax -s -o test.html test.md
经试验,这样转化的HTML文件可以在Firefox以及Microsoft的 Edge浏览器和Internet Explorer浏览器中正常显示数学公式。 如果公式中的中文显示不正常, 对显示的公式右键单击弹出选项菜单, 选择"Math Settings--Math Renderer--SVG"或者"HTML-CSS"。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
layout: post
title: "R制作研究报告"
date: 2019-11-29
tag: sas
20 用R制作研究报告
一个统计或数据分析的科研项目, 都会产生一个或多个研究报告。 因为使用统计与数据分析不可避免地有很多计算涉及在内, 这里假设使用R软件做了计算。 科研是一个不断改进的过程, 所以每一次重新做了计算, 研究报告中的汇总表格、图形都要更新。 这样的任务比较繁琐, 也容易出错。
"文学式编程"(literate programming, (Knuth 1984))是这样一种思想, 把撰写报告与计算程序有机地结合在一起, 用一个源文件文件既包含报告内容, 又包含计算程序。 每次产生研究报告时, 先运行源文件中的计算程序得到计算结果, 这些结果包括文字性内容与图形, 然后利用适当软件自动地把这些原始文字、计算结果组合成最终的报告。 利用这样的思想, 可以自动生成重复的例行报告, 还可以作为"可重复科学研究"的载体。
上述的源文件一般是文本文件, 格式可以是Markdown格式, 也可以是LaTeX格式等许多格式。 R的knitr软件包就是用来支持这样的编程思想的一个扩展包。
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名, 利用R程序进行扩展的版本保存为.Rmd扩展名。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。 Markdown仅适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过LaTeX编译器可以转换为PDF格式, 也可以将docx转存为PDF格式, 或者用输出到PDF文件的打印机将网页格式转换为PDF格式。
LaTeX是一个文档排版系统, 功能强大,结果美观, 设计合理。 缺点是需要学习类似于HTML的另一种语言。 LaTeX源文件主要是编译为PDF。
R扩展包knitr包支持在Markdown格式、LaTeX格式等类型的文件中插入R代码, 经过转换, 文中的R代码可以变成代码的结果文字、表格、图形, 与原有报告文字有机地结合在一起。
插入了R代码的markdowng格式的文件一般以.Rmd为扩展名, R的rmarkdown扩展包和knitr包一起为Rmd格式提供了支持。
R的bookdown包进一步增强了R Markdown格式的功能, 支持生成PDF、多文件互相链接的HTML、Word等输出, 其中的表格、图形可以变成浮动表, 公式、定理可以自动编号并支持文献、公式、定理、图表、章节的引用和链接, 所以比较适用于编写一本书或论文、研究报告。
knitr包也支持在LaTeX源文件中插入R代码, 通过编译使得R代码运行结果、图形自动插入生成的研究报告中。 原来有一个Sweave扩展包是支持在LaTeX中插入R代码的, 现在knitr的功能已经涵盖并增强了此包功能。
下面几章分别介绍markdown格式、R markdown格式、bookdown扩展包、简易网站制作和幻灯片制作。 参考:
利用R Markdown格式可以执行如下的任务:
- 将单一的R Markdown文件编译为不同的格式,如:
- HTML;
- PDF;
- MS Word。
- 在RStudio软件内制作笔记本文档,可以在其中包含说明文字与R代码, 可以在笔记本文档内交互地运行R代码并能将结果交互地显示在笔记本内。
- 生成演示幻灯片,可以是基于HTML5的,也可以是基于LaTeX beamer扩展包的, 或者MS Powerpoint。
- 编写多章节组成的书籍。
- 编写期刊论文。
- 制作网站或者博客。
- 制作商业智能仪表盘(dashboards),即数据可视化展示。
References
Knuth, Donald E. 1984. "Literate Programming." The Computer Journal 27 (2): 97--111.
Xie, Yihui. 2017. Bookdown: Authoring Books and Technical Documents with R Markdown.
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
21 Markdown格式
21.1 介绍
Markdown是一种很简单的文本文件格式, 通常保存为.md扩展名。 Mardown中文内容应该使用UTF-8编码。 Markdown文件里面有一些简单的格式标注方法, 比如两个星号之间的文字会转化为斜体, 缩进四个空格或一个制表符的内容会看成代码。
Markdown适用于比较简单的文章、源程序说明等, 不太适用于复杂的含有大量数学公式、图表的文章, 从markdown格式比较适合转换为html(网页)格式, 也可以转换为MS Word的docx格式, 通过docx格式可以转存为PDF格式。 R扩展包knitr、rmarkdown和bookdown与pandoc软件一起大大扩展了markdown格式的适用范围。
如果需要作为一本书发布在网站上或者出版, 可考虑使用R的bookdown扩展包。 如果需要对出版格式进行精确控制, 可考虑用LaTeX格式, LaTeX格式很复杂, 学习比较困难, 但是表达能力强。
21.2 Markdown格式文件的应用
Markdown格式用在一些微博、论坛中作为缺省格式, 用户在网络浏览器软件的输入框中按照markdown格式输入, 网站自动将其转换为html富文本内容显示出来。
因为markdown格式就是纯文本, 而且其格式十分简单, 所以可以仅仅用普通文本编辑器编写markdown格式的文件, 不需要转换为其它格式。
有一些独立运行的编辑软件, 在其中输入了markdown格式文件后, 可以并列地显示转化为html富文本后的结果, 很多还支持自动备份到云服务中。 但是,这些独立运行的编辑器大都有商业因素。 比如,国内的印象笔记软件是提供了云存储的笔记软件, 在其PC端就支持创建markdown格式的笔记, 可以在输入时即时显示html效果。
RStudio软件不是专用的Markdown编辑器, 它是一个R程序的集成编辑、运行环境, 对个人用户免费, 在R Studio中可以编辑Markdown文件和含有R代码的Markdown文件, 可以一键将其转化成HTML、MS Word docx文件, 在单独安装的LaTeX编译软件支持下还可以直接编译成PDF。 RStudio支持下的增强的Mardown格式, 称为RMarkdown格式, 以.Rmd为扩展名, 支持大多数的LaTeX公式, 在bookdown扩展包支持下还支持公式、定理、图表等自动编号和引用、链接。
21.3 markdown格式说明
这部分内容参考了markdown手册和Rstudio的文档, 以及(Xie, Allaire, and Grolemund 2019)。
21.3.1 概述
Markdown格式是John Gruber于2004年创造的, Markdown 的目标是实现"易读易写"。 Markdown定义了一种简单好用的文本文件格式, 作为单独的文本文件, 此格式没有什么多余的标签, 又可以转化为很多其它的格式。
Markdown 的语法全由一些符号所组成, 这些符号经过精挑细选,其作用一目了然。 比如:在文字两旁加上星号,看起来就像强调。 Markdown 的列表看起来就像我们平常在邮件中写一个列表的方法。 Markdown 的区块引用看起来就真的像是引用一段文字, 就像你曾在电子邮件中见过的那样。
需要时, 可以直接在markdown中写HTML标记内容。 markdown能实现的功能是HTML的一部分, 但是比HTML内容更干净, 没有掺杂过多的与要表达的意思无关的标签。 Markdown的理念是,能让文档更容易读、写和随意改。
21.3.2 段落
一个段落由一行或连续的多行组成。 段落之间以空行分隔。 同一段落内的不同行在转换成HTML或docx等格式后会重新排列, 原来的段内换行被当成了空格,这样的规定与LaTeX类似。 普通段落不该用空格或制表符来缩进, 不应在行尾留有空格。
为了在段内换行并且转化后仍保持段内换行, 输入时在前面行的末尾输入两个或两个以上空格。例如:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
显示结果为:
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
这样做的缺点是末尾的空格时不可见的。 可以使用HTML的 标签在段内换行,如:
白日依山尽,黄河入海流。<br>
欲穷千里目,更上一层楼。
结果为
白日依山尽,黄河入海流。
欲穷千里目,更上一层楼。
21.3.3 段内文字格式
在一段内,用星号或下划线包围的内容如*强调*是强调 格式。 用双星号或双下划线包围的内容如**加重**是加重格式。 星号、下划线与要强调或加重的内容之间不要空开, 否则会当作普通星号或下划线解释, 在行首还会当作列表。 为了插入普通的星号或下划线,可以使用反斜杠保护, 或者写成段内代码格式。
可以用一对~作为界定符给出下标, 如HO~2~会变成HO2。 可以用一对^作为界定符给出上标, 如Cu^2+^会变成Cu2+。 但是,数学公式一般还是应该使用LaTeX数学公式形式(见22.8)。
在普通段落内一部分内容希望显示成代码, 对其中的特殊字符不进行解释, 只要包在两个反向单撇号内。 如if(_x_ > 0) y=1;会变成if(_x_ > 0) y=1;。 如果内容本身就包含反向单撇号, 可以在两边使用更多个数的反向单撇号, 如````x` ```会变成x。
在Markdown文件中, 为了使得某些有特殊意义的字符不作特殊解释, 可以在该字符前面加上反斜杠\, 取消其特殊含义。
在Rmarkdown文件中, 为了原样显示反向单撇号, 可以在两边用双写的反向单撇号界定字符串。
21.3.4 标题和分隔线
以一个井号#开始的行是一级标题, 以两个井号#开始的行是二级标题, ............, 以六个井号#开始的行是六级标题。 标题行前面应该空一行, 否则可能把某些偶然出现在行首的#号误认为标题行的标志。
对一级标题, 也可以用标题内容下面输入一行等于号=表示上一行内容是一级标题。 对二级标题, 可以用标题内容下面输入一行减号-表示上一行内容是二级标题。 等于号和减号的个数不限。
用三个或三个以上连续的星号组成的行, 可以转换成分隔线。下面是一个分隔线:
21.3.5 引用段落
可以用类似Email的回复包含原始邮件内容的办法输入引用段落, 即,在段落的每行前面加一个大于号。 比如下面的诗:
> 白日依山尽,黄河入海流。
> 欲穷千里目,更上一层楼。
转换成
白日依山尽,黄河入海流。 欲穷千里目,更上一层楼。
注意引用也是段落模式,内容中的换行不起作用,空行导致分段。
引用段落也可以仅在段落第一行写大于号, 其它行顶格写,例如下面的两段引用:
> 远上寒山石径斜,
白云生处有人家。
>
> 停车坐爱枫林晚,
霜叶红于二月花。
转换成
远上寒山石径斜, 白云生处有人家。
停车坐爱枫林晚, 霜叶红于二月花。
引用也可以嵌套,如:
> 张三说:李四这样说过
>
>> 不想当将军的木匠不是好厨子。
>
转换成
张三说:李四这样说过
不想当将军的木匠不是好厨子。
注意嵌套内容前后都有空的引用行,否则不能实现嵌套引用。
引用内也可以嵌套其它的Markdown格式如标题、列表等。 引用前后应该有空行把引用内容与其他内容分隔开。
21.3.6 列表
列表分为不编号的列表和编号的列表。 不编号的列表转化后通常显示圆点开头的列表项。
在Markdown中, 用星号表示一个不编号的列表项。 星号也可以替换成加号或减号, 后面必须有一个或多个空格。 每个列表项可以输入多行, 各行的内容最好左对齐, 左对齐在使用文本格式时较易阅读, 但不是必须的。 两个列表项之间不要空行。 例如:
* 白日依山尽,
黄河入海流。
* 欲穷千里目,
更上一层楼。
转换为
- 白日依山尽, 黄河入海流。
- 欲穷千里目, 更上一层楼。
段落顶头的数字加句点和空格表示编号列表, 两个列表项之间尽量不要空行。 例如:
1. 第一种解决方法,
收买敌人的高官。
2. 第二种解决方法,
尽可能拖延。
转换为
- 第一种解决方法, 收买敌人的高官。
- 第二种解决方法, 尽可能拖延。
标准的markdown编号列表不能自己定义数字的显示格式, 不允许开始值不等于1。 pandoc支持更自由的列表, 允许输入时有括号或右括号,允许使用字母和罗马数字,但是括号会被去掉。如
(1) 顶层一;
a) 内层二;
b) 内层三;
(2) 顶层二。
转换为
- 顶层一;
- 内层二;
- 内层三;
- 顶层二。
为了避免错误地产生非本意的编号列表, 在行首写数字加句点和空格时,可以在句点前加反斜杠, 或者在句点前加空格。例如,下面是一个年号:
2016\.
如上输入将不会错误地解释为有序列表。
如果列表项目中有多个段落, 这时两个列表项之间应该以空行分隔, 每个项目除了第一行外,输入的每行内容都应该缩进4个空格或者一个制表符。 例如:
* R语言第一个版本开发于1976-1980,基于Fortran;
于1980年移植到Unix, 并对外发布源代码。
1984年出版的"棕皮书"
总结了1984年为止的版本, 并开始发布授权的源代码。
这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新,
变成了我们现在使用的S语言,称为第二版。
1988年出版的"蓝皮书"做了总结。
* 1992年出版的"白皮书"描述了在S语言中实现的统计建模功能,
增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。
现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
转换为
-
R语言第一个版本开发于1976-1980,基于Fortran; 于1980年移植到Unix, 并对外发布源代码。 1984年出版的"棕皮书" 总结了1984年为止的版本, 并开始发布授权的源代码。 这个版本叫做旧S。与我们现在用的S语言有较大差别。
1989--1988对S进行了较大更新, 变成了我们现在使用的S语言,称为第二版。 1988年出版的"蓝皮书"做了总结。
-
1992年出版的"白皮书"描述了在S语言中实现的统计建模功能, 增强了面向对象的特性。软件称为第三版,这是我们现在用的多数版本。
1998年出版的"绿皮书"描述了第四版S语言,主要是编程功能的深层次改进。 现行的S系统并没有都采用第四版,S-PLUS的第5版才采用了S语言第四版。
列表项目内如果有引用段落, 需要都缩进4个空格。 如果有程序代码, 需要缩进4个空格后用三个反单撇号表示开始与结束。
列表可以嵌套, 嵌套的列表需要缩进4个空格, 中间不需要空行。 例如:
1. 第一类工作包括:
+ 技术服务;
+ 咨询服务。
2. 其它工作略。
转换为
- 第一类工作包括:
- 技术服务;
- 咨询服务。
- 其它工作略。
如果需要把每个列表项当作段落排版,可以在每个列表项后空行。
21.3.7 源程序
为了让源程序能够自动显示成源程序的样式, 而不至于自动分行、特殊字符解释, 用空行把源程序与其它内容隔开, 并把源程序行都缩进4个空格(或以上)或者一个制表符。 源程序格式持续到不缩进4个空格的地方为止。
例如,下面的输入:
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
转换为
f <- function(x){
n <- length(x)
y <- numeric(n)
y[x >= 0] <- 1
##y[x < 0] <- 0
y
}
更适当的做法是用三个连续的反向单撇号表示代码开头与代码结束, 中间就会当作源程序代码处理。 例如下面的输入
```
> x <- rnorm(100)
> hist(x)
```
转换为
> x <- rnorm(100)
> hist(x)
R的knitr包在Markdown格式的文件中插入R可执行代码时, 就用了这样的方法。 而且,R Markdown格式的代码块不需要用空行与前后分隔开。
在pandoc程序的支持下, 代码段还可以采用栅栏式代码段, 在代码段开头前面一行加上至少三个连续~符号, 在结尾后面一行加同样数目的~符号。 这样的代码段前后也必须空行以与其它内容分开。 另外,如果代码内本身含有~行, 只要使得开头与结尾标志中的~个数更多就可以了。 例如下面的输入
~~~
#include <math.h>
double sqr(double x){
return(x*x);
}
~~~
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
使用栅栏式代码段时可以在开始行尾写大括号, 在大括号内写选项。 其中一种选项是要求按照某种编程语言对结果进行彩色语法显示, 如.cpp表示C++,.c表示C,.r表示R,.python表示python等。 选项.numberLines要求该代码行编号, 选项startFrom=指定开始行号。如 如:
~~~{.cpp .numberLines startFrom=101}
#include <math.h>
double sqr(double x){
return(x*x);
}
~~~
转换为
#include <math.h>
double sqr(double x){
return(x*x);
}
21.3.8 链接
最简单的链接是原样显示的可点击的链接, 只要把链接地址用小于号和大于号包在中间, 两边用空格和其它内容隔开。 如果是网页,需要加http://, 如果是邮箱,需要加mailto:。 例如,如下代码:
北京大学的网页地址是: <http://www.pku.edu.cn/> 。
显示为
北京大学的网页地址是: http://www.pku.edu.cn/ 。
除此之外, Markdown 还支持两种形式的链接语法: 行内式和引用式两种形式。 不管是哪一种,链接的显示文字都是用方括号[...]来标记。
要建立一个行内式的链接, 只要在方括号内写链接的显示文字, 右方括号后面紧接着圆括号, 并在圆括号中间插入网址链接即可。 方括号部分与圆括号部分之间不能断开。 例如:
请参考:[李东风的教学主页](http://www.math.pku.edu.cn/teachers/lidf/course/index.htm)
变成了
请参考:李东风的教学主页
在圆括号中,链接后面还可以包含用双撇号包围的标题文字, 与链接之间用空格分开。
引用式的链接, 需要在某处(比如文章结尾)定义一些链接的标识符, 然后用方括号包围链接的显示文字, 后面紧接着方括号包围着链接的标识符。
为了定义链接标识符, 用方括号包围链接标识符, 前面可以有至多3个空格缩进, 右方括号后面紧接着冒号和一个空格, 空格后写链接地址, 然后空格,在两个双撇号中间写一个链接地址的标题。 例如
[baidu]: http://baidu.com/ "百度"
[pku]: http://www.pku.edu.cn/ "北大"
这时,在文章中就可以用标识符调用链接, 如[北京大学主页][pku]将变成链接北京大学主页。
使用引用式的链接, 有些像论文中把所有参考文献排列在文章末尾, 文中用到某一篇文献只要提及其序号。
还有一种链接是内部链接,用于文内跳转。 在各级标题行的末尾, 可以添加{#自定义标签}这样的内容, 其中"自定义标签"是自己写的一个标识符, 标识符仅使用英文字母、数字、下划线、减号, 用来区分不同的位置。 比如,本文第一节"介绍"添加了markdown-intro为标签, 就可以用"[回到介绍](#markdown-intro)"产生链接 回到介绍。
21.3.9 插入图形
图形只能用链接形式, 不可能保存到一个纯文本文件内。 图形文件可以存在于远程服务器上, 也可以是与生成的HTML文件在同一目录结构中的文件。 语法仍使用行内式和参考式两种形式。 转化成HTML、PDF、Word格式后可以把图形内嵌在输出文件内部。
行内式的图片链接, 是普通行内链接格式前面添加了一个叹号, 惊叹后面紧接着方括号, 方括号内写图片的标题,标题可以空缺, 在右方括号后面紧接着圆括号, 圆括号内写图片的链接。
例如,下面的代码可以插入百度的一个logo,使用的是网上的资源:

结果为

为了插入保存在本地的与Markdown源文件在同一子目录或下级子目录的图形, 只要在圆括号中写图片文件名(如果与Markdown源文件在同一子目录)或相对路径。 例如,在D:\work\figs下的图形文件baidu_logo.gif在本Markdown源文件所在目录的figs子目录中, 可以用代码

结果为

这样含有网上图片和本地图片的Markdown源文件转化为HTML和docx格式, 都可以正常显示插入的图片。
与链接类似, 也可以在文章某处(比如末尾)定义图片的标识符, 然后把行内图片引用中图片地址替换成图片标识符即可。
21.3.10 表格
Markdown文本格式的表格就像是用减号、等号、竖线画的文本格式表格一样, 转化为HTML、docx等格式后就变成了富文本的表格。 有如下几种表格:
- 管道表
- 简单表
- 换行表
- 有格表
21.3.10.1 管道表
管道表在两列之间用竖线分开, 在列标题下面用减号画横线, 用如下方法指定各对齐方式:
- 在列标题下的横线开始加冒号,表示左对齐;
- 在列标题下的横线末尾加冒号,表示右对齐;
- 在列标题下的横线两端加冒号,表示居中对齐;
- 列标题下面仅有横线没有冒号,表示缺省对齐方式,一般是左对齐。
在表格内容后面空一行后写用Table:开头的表格说明。
这种方法不需要输入内容上下对齐,适用于中文内容。 后面所讲的简单表、换行表、有格表需要能够输入内容对齐, 对于中英文混合内容很难做到对齐, 所以仅管道表比较适合中文内容。
例如:
| 姓名 | 收入 | 职业 | 颜色偏好 |
|:------|-----------:|:---------------:|-----------|
| 赵四海 | 123456 | 业务经理 | 红 |
| 刘英 | 50 | 无 | 蓝 |
| 钱德里 | 3200 | 保洁 | 灰 |
Table: 管道表示例
结果为
| 姓名 | 收入 | 职业 | 颜色偏好 |
|---|---|---|---|
| 赵四海 | 123456 | 业务经理 | 红 |
| 刘英 | 50 | 无 | 蓝 |
| 钱德里 | 3200 | 保洁 | 灰 |
管道表不允许输入单元格换行, 单元格内容太宽时转换结果可能自动换行, 自动换行时列宽度与输入的列标题下横线宽度成比例。
21.3.10.2 简单表
简单表的格式是, 第一行是各列标题, 第二行是各标题下面用减号组成的表格线, 同一行的不同列要用空格分开, 从第三行开始是内容。
在表格前或表格后用空行隔开的以Table:开头的行是表格说明或标题。
为了确定表格每列单元格内容如何对齐, 用列标题下的表格线给出提示:
- 表格线与列标题右对齐,表示该列右对齐;
- 表格线与列标题左对齐,表示该列左对齐;
- 列标题在表格线中间,表示该列居中对齐;
- 列标题左右都与表格线对齐,表示该列为缺省对齐方式,一般是左对齐。
一定要使用一个等宽字体来编辑这样的表格,否则对齐与否无法准确分辨。 单元格内容不能超出表格线左端。 经过试验发现, 中文内容很难按这种方法对齐。
例如:
Name Income Job Color
------ -------- ------------------ -----
Jane 123456 Research Assistant red
John 50 N/A blue
William 3200 Cleaner blue
Table: 一个简单表的例子
结果为:
| Name | Income | Job | Color |
|---|---|---|---|
| Jane | 123456 | Research Assistant | red |
| John | 50 | N/A | blue |
| William | 3200 | Cleaner | blue |
21.3.10.3 换行表
换行表在输入列标题和单元格内容时, 允许输入内容拆分行,但是转化后并不拆分行。 这样的表以一行减号开始,以一行减号结束, 中间的表格用空行分开实际的不同行。 例如:
----------------------------------------------------
Name
of
Subject Income Job color
------ -------- ------------------ -----
Jane 123456 Research red
Ayer Assistant
John 50 N/A blue
Tukey
William 3200 Cleaner blue
Tale
----------------------------------------------------
Table: 一个换行表的例子
结果为:
| Name of Subject | Income | Job | color |
|---|---|---|---|
| Jane Ayer | 123456 | Research Assistant | red |
| John Tukey | 50 | N/A | blue |
| William Tale | 3200 | Cleaner | blue |
换行表输入时各列的输入宽度是有作用的, 输入较宽的列结果也较宽。
21.3.10.4 有格表
完全用减号、竖线、等于号、加号画出表格线。 这样的表在文本格式下呈现出很好的表格形状。 转化后不能指定对齐方式。
例如:
Table: 有格表示例
+---------------+---------------+--------------------+
| Fruit | Price | Advantages |
+===============+===============+====================+
| Bananas | $1.34 | - built-in wrapper |
| | | - bright color |
+---------------+---------------+--------------------+
| Oranges | $2.10 | - cures scurvy |
| | | - tasty |
+---------------+---------------+--------------------+
结果为
| Fruit | Price | Advantages |
|---|---|---|
| Bananas | $1.34 | built-in wrapperbright color |
| Oranges | $2.10 | cures scurvytasty |
21.4 附录:pandoc软件介绍
pandoc是一个杰出的开源软件, 作者为John MacFarlane。 RStudio软件中已经包含了这个软件。 软件在命令行运行, 可以用来在多种不同的文件格式之间进行转换, 输入格式一般是文本格式, 比如markdown、LaTeX、MediaWiki、reStructured Text、 HTML、DocBook, 但是也可以输入MS Word docx、Open Office ODT、EPUB格式。 输出可以是这些文本格式, 也可以是MS Word docx、Open Office ODT、EPUB、LaTeX等格式, 在安装了LaTeX编译系统如MikTeX时可以输出为PDF。 RStudio软件中包括了一份pandoc软件程序。
可以用普通文本编辑器编写markdown格式的文件, 用pandoc转换为HTML或MS Word docx等格式。 因为pandoc需要UTF8编码的输入文件, 所以应该把markdown文件保存为UTF格式, MS Windows下的Notepad++软件可以很容易地编辑文本文件 并在各种编码之间转换。 实际上,MS Windows下有一个markdown编辑程序Smarks就是基于pandoc软件的。
首先, 从pandoc网站下载并安装pandoc。 安装程序很奇怪地安装到了 C:\Users\登录用户名\AppData\Local\Pandoc中, 请将此子目录复制到一个合适的位置, 比如C:\Pandoc。 如果把此路径加入到Windows系统的可执行文件搜索路径中 (在"控制面板-系统和安全-系统-高级系统设置-环境变量"中, 为系统变量的Path添加一个分号分开的路径C:\Pandoc即可以不用全路径访问 pandoc.exe可执行文件。
为了用pandoc转化某个markdown文件, 首先在该文件所在子目录打开一个Windows命令行窗口, 在MS Win10系统中只要在文件管理器的"文件"菜单选择 "打开命令提示符"即可。 比如,文件名是test.md, 用如下pandoc命令可以转换为.docx文件(MS Word文件的新版本):
C:\Pandoc\pandoc -o test.docx test.md
用如下pandoc命令可以转换为.html文件:
C:\Pandoc\pandoc -s -o --mathjax test.html test.md
如果把pandoc.exe加入了Windows操作系统的Path环境变量中, 上面的 C:\Pandoc\pandoc 可以简写为 pandoc。
pandoc在其它操作系统中也有相应的版本。 软件下载与文档见Pandoc的网站http://pandoc.org。
如果使用RStudio编辑markdown文件或者R Markdown文件, 它会自动调用内置的pandoc程序。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.
22 R Markdown文件格式
22.1 R Markdown文件
借助于R的knitr和rmarkdown扩展包的帮助, 可以在Markdown格式的源文件中插入R代码, 使得R代码的结果能够自动插入到最后生成的研究报告中。 这种格式称为R Markdown格式,简称为Rmd格式, 相应的源文件扩展名为.Rmd。 输出格式可以是HTML、docx、pdf、beamer等。 R Markdown的基础格式是markdown格式, 严格说来是Pandoc软件支持的增强版的markdown格式, 比如, 支持LaTex格式的数学公式, 支持各种编程语言语法彩色加亮显示,等等。
knitr的详细文档参见网站knitr文档。 关于R Markdown可参考专著(Xie, Allaire, and Grolemund 2019)。 RStudio网站提供了一个R Markdown使用摘要下载: (rmarkdown-2.0.pdf)[rmarkdown-2.0.pdf]。 Pandoc的文档见pandoc网站。
一个Rmd文件中包含元数据(metadata)、正文内容和R代码三种成分, 比如,下面是一个简单的Rmd文件样例:
---
title: "R语言简介"
author: "李东风"
date: "2019-08-29"
output: html_document
---
这里是正文段落。
段落中仍可以利用一般的Markdown语法,
比如在两边用双星号表示**粗体加重**,
在用两边反单撇号表示代码,如`y <- sin(x)`。
下面是一个R代码段,有文字输出:
```{r}
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
```
下面是一个R代码段,有图形输出:
```{r}
plot(x)
```
下面是一个R代码段,
有富文本表格输出:
```{r}
knitr::kable(as.data.frame(x))
```
在文字段落内部也可以有代码,
比如,x的第一个元素值为`r x[1]`。
```
在文件开头用三个减号组成的行包围的内容称为元数据 , 可以用来规定文章标题、作者、日期、输出格式、输出设置等属性。 见22.11。
22.2 R Markdown文件的编译
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。 用快捷图标Knit可以将文件转换成HTML格式、PDF格式(需要安装LaTeX编译软件)、MS Word格式。
从HTML格式可以转换成PDF格式。 为此, 安装Google的Chrome浏览器, 在Chrome中打开HTML文件后, 从Chrome浏览器的菜单中找到打印菜单, 从中选择打印机为"保存到PDF"选项, 就可以将HTML网页转换成PDF, 其中的数学公式、表格、图形都可以比较好地转换。 但是,经试验,slidy幻灯片用Internet Explorer浏览器转换PDF更合适。 其它浏览器在转换数学公式时容易将公式右侧的编号裁切掉。
从Word文件也可以转换成PDF格式, 用MS Word软件的"文件-导出"或者"文件-另存为"功能即可。
如果想将R Markdown文件借助于LaTeX格式转换为PDF, 需要在系统中安装一个TeX编译器, 如MS Windows下有MikTeX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包。
如果不借助于RStudio软件, 可以用R软件、knitr包、rmarkdown包、pandoc软件来完成R Markdown源文件的编译。 比如,假设test.Rmd是一个这样的R Markdown格式的文件, 注意一定要使用UTF-8编码保存, 可以在R或RStudio中运行如下命令以生成含有运行结果的html文件:
rmarkdown::render("myfile.Rmd", output_format = "html_document", encoding="UTF-8")
其中myfile.Rmd是源文件, 产生的HTML文件带有图形、支持数学公式。
在R或RStudio中可以用如下命令把.Rmd文件转化为MS Word docx格式:
rmarkdown::render("myfile.Rmd", output_format = "word_document", encoding="UTF-8")
使用RStudio软件使得这些任务可以一键完成, 而且有很好的数学公式支持, 所以建议编辑R Markdown文件还是使用RStudio软件。
用RStudio的Knit图标一键编译与用rmarkdown::render()命令编译有一个重要差别:
- 用Knit图标编译,Rmd文件中的程序会在一个崭新的会话中执行, 当前会话中已经定义的函数、变量、导入的扩展包不会影响到编译结果;
- 用
rmarkdown::render()编译, Rmd文件中的程序是在当前会话中执行的, 会带来一定的兼容性问题, 有可能在别人的环境下就不能正确执行或者会给出不同结果。 但是,rmarkdown::render()可以通过程序调用, 比如,循环地从同一个Rmd生成一系列不同的报告。 为了不让当前会话环境干扰结果, 可以人为地打开一个新会话。
22.3 在R Markdown文件中插入R代码
插入的R代码分为行内代码与代码块。
行内代码的结果插入到一个段落中间, 代码以``r开头,以```结尾, 如r sin(pi/2)`在结果中会显示为1。 为了原样显示一个反向单撇号, 可以在两边用双反向单撇号界定并用空格隔开内部的内容。
代码块则把结果当作单独的段落, 按照Markdown格式的规定, 代码块的前后需要有空行, 但是R Markdown实际上放松了这个要求, 允许前后不空行。 R代码段以单独的一行开头, 此行以三个反单撇号开始, 然后是{r},如````{r}`。 代码段以占据单独一行的三个反单撇号`````结尾。 如
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
结果将变成
set.seed(1)
x <- round(rnorm(10), 2)
print(x)
## [1] -0.63 0.18 -0.84 1.60 0.33 -0.82 0.49 0.74 0.58 -0.31
可以看出,代码段程序会被插入到最终结果中, 代码段的文本型输出会插入到程序的后面。
代码块也可以嵌入到引用、列表等环境中。
代码块中作的图将自动插入到当前位置。 下面的程序:
plot(x)
结果将显示为:
plot(x)

在RStudio中, 可以用Insert快捷图标插入代码段, 还可以用Ctrl+Alt+I快捷键插入代码段。
22.4 输出表格
knitr包提供了一个 kable() 函数可以用来把数据框或矩阵转化成有格式的表格, 支持HTML、docx、LaTeX等格式。
例如,计算线性回归后, summary()函数的输出中有coefficients一项,是一个矩阵, 如果直接文本显示比较难看:
x <- 1:10; y <- x^2; lmr <- lm(y ~ x)
co <- summary(lmr)$coefficients
print(co)
## 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函数来显示:
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 |
kable()函数的digits=选项可以控制小数点后数字位数, caption=选项可以指定表的标题内容。
R扩展包xtable提供了一个xtable()函数, 也可以用来生成HTML格式和LaTeX格式的表格, 但是需要指定要输出的格式。 xtable对比较多的R数据类型和输出类型提供了表格式显示功能, 包括矩阵、数据框、回归分析结果、方差分析结果、主成分分析结果、 若干分析结果的summary结果等。 例如,上面的回归结果用xtable()函数显示如:
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的结果不可用。
R扩展包pander提供了更好的表格能力, 也能与knitr包很好的合作输出。 其pander()函数可以将多种R输出格式转换成knitr需要的表格形式。 如
pander::pander(lmr)
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | -22 | 5.55 | -3.964 | 0.004153 |
| x | 11 | 0.8944 | 12.3 | 1.778e-06 |
但是,经过试验发现, 表中中有中文时pander包会出错。
22.5 利用R程序插图
Rmd文件的插图有两种, 一种是已经保存为图形文件的, 主要是png和pdf图片; 另一种是文中的R代码生成的图形。
已经有图形文件的, 可以用markdown格式原来的插图方法, 见markdown格式介绍。 但是,这样做不能给图形自动编号, 另外因为制作图书是有网页和PDF书两种主要输出格式的, 原有的插图方式在这两种输出格式上有细微的不一致。 所以,最好是统一使用Rmd的插图方法。
Rmd的插图方法就是写一段R代码段来插图, 如果是用程序作图,则代码中写作图的代码; 如果是已有的图形文件, 可以在一个单独的R代码段中用类似下面的命令插图:
```{r, echo=FALSE}
knitr::include_graphics("figs/myfig01.png")
```
knitr::include_graphics("figs/myfig01.png")
其中figs是存放图形文件的子目录名, myfig01.png是要插入的图形文件名。 这样, 如果同时还有myfig01.pdf的话, 则HTML输出使用png图片而PDF输出自动选用pdf文件。 另外, 插图的选项在代码段的选项中规定: 用代码段的fig.with和fig.height选项指定作图的宽和高(英寸), 用out.width和out.height选项指定在输出中实际显示的宽和高, 实际显示的宽和高如果使用如"90%"这样的百分数单位则可以自动适应输出的大小。
由于PDF中的中文编码不能自动识别, 所以在每个Rmd源文件的开头应该加上如下的设置, 使得生成PDF图时中文能够正确显示:
```{r setup-pdf, include=FALSE}
pdf.options(family="GB1")
```
其中include=FALSE表示要不显示代码段的代码, 有运行结果也不插入到输出结果中, 是否运行视缺省的eval=的值而定。
22.6 代码段选项
独立代码段以````{r}开头, 在大括号内还可以写一些选项, 选项之间以及与开始的r之间用逗号分隔, 所有选项写在同一行内不要换行。 选项都使用"选项名=选项值"的格式, 选项值除了使用常量外也可以使用全局变量名或表达式。 在大括号内开头的 r`空格后写一个由英文大小写字母、数字、减号组成的标识符, 作为代码段的标签。 标签中不要用其它类型的字符, 下划线也不要用。 如
```{r firstCode}
cat('This is 第一段, 有标签.\n')
```
关于代码段选项, 详见https://yihui.name/knitr/options。
22.6.1 代码和文本输出结果格式
R代码块和R代码块的运行结果通常是代码块原样输出, 运行结果用井号保护起来, 这样有利于从文章中复制粘贴代码。 如:
```{r}
s <- 0
for(x in 1:5) s <- s + x^x
s
```
结果为:
s <- 0
for(x in 1:5) s <- s + x^x
s
## [1] 3413
22.6.1.1 highlight选项
转化后的R代码块缺省显示为彩色加亮形式。 用选项highlight=FALSE关闭彩色加亮功能。
22.6.1.2 prompt和comment选项
如果希望代码用R的大于号提示符开始, 用选项prompt=TRUE。 如果希望结果不用井号保护, 使用选项comment=''。 例如:
```{r prompt=TRUE, comment=''}
sum(1:5)
```
结果为:
> sum(1:5)
[1] 15
22.6.1.3 echo选项
如果希望不显示代码, 加选项echo=FALSE。 如
```{r echo=FALSE}
print(1:5)
```
结果为:
## [1] 1 2 3 4 5
22.6.1.4 tidy选项
加选项tidy=TRUE可以自动重新排列代码段, 使得代码段格式更符合规范。例如:
```{r tidy=TRUE}
s <- 0
for(x in 1:5) {s <- s + x^x; print(s)}
```
结果为:
s <- 0
for (x in 1:5) {
s <- s + x^x
print(s)
}
## [1] 1
## [1] 5
## [1] 32
## [1] 288
## [1] 3413
22.6.1.5 eval选项和include选项
加选项eval=FALSE, 可以使得代码仅显示而不实际运行。 这样的代码段如果有标签, 可以在后续代码段中被引用。
加选项include=FALSE, 则本代码段仅运行, 但是代码和结果都不写入到生成的文档中。
22.6.1.6 child选项
加选项child='文件名.Rmd'可以调入另一个.Rmd文件的内容。 如果有多个.Rmd文件依赖于相同的代码,可以用这样的方法。
22.6.1.7 collapse选项
一个代码块的代码、输出通常被分解为多个原样文本块中, 如果一个代码块希望所有的代码、输出都写到同一个原样文本块中, 加选项collapse=TRUE。 例如, 没有这个选项时:
```{r}
sin(pi/2)
cos(pi/2)
```
结果为:
sin(pi/2)
## [1] 1
cos(pi/2)
## [1] 6.123032e-17
代码和结果被分成了4个原样文本块。 加上collapse=TRUE后,结果为:
sin(pi/2)
## [1] 1
cos(pi/2)
## [1] 6.123032e-17
代码和结果都在一个原样文本块中。
22.6.1.8 results选项
用选项results=选择文本型结果的类型。 取值有:
markup, 这是缺省选项, 会把文本型结果变成HTML的原样文本格式。hide, 运行了代码后不显示运行结果。hold, 一个代码块所有的代码都显示完, 才显示所有的结果。asis, 文本型输出直接进入到HTML文件中, 这需要R代码直接生成HTML标签, knitr包的kable()函数可以把数据框转换为HTML代码的表格。
例如:results='hold'的示例:
```{r collapse=TRUE, results='hold'}
sin(pi/2)
cos(pi/2)
```
结果为:
sin(pi/2)
cos(pi/2)
## [1] 1
## [1] 6.123032e-17
22.6.1.9 错误信息选项
选项warning=FALSE使得代码段的警告信息不进入编译结果, 而是在控制台(console)中显示。 有一些扩展包的载入警告可以用这种办法屏蔽。
选项error=FALSE可以使得错误信息不进入编译结果, 而是出错停止并将错误信息在控制台中显示。
选项message=FALSE可以使得message级别的信息不进入编译结果, 而是在控制台中显示。
22.6.2 图形选项
22.6.2.1 图形大小
用fig.width=指定生成的图形的宽度, 用fig.height=指定生成的图形的高度, 单位是英寸(1英寸等于2.54厘米)。
下面给出一个长宽都是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)

fig.width=和fig.height=规定的是生成的图形大小, 实际生成图形的显示大小会受到dpi(分辨率)影响, 默认dpi是72(每英寸72个点), 也可以用dpi=选择分辨率。 转化后的HTML文件显示时不一定按原始大小显示。 用out.width=和out.height=可以指定显示大小, 但是必须是最终文件格式承认的单位, 比如HTML的图形大小单位是点(平常说屏幕分辨率的单位)。 或者写成如90%这样的百分比格式。 例如在上面的例子中加上输出度为页面宽度80%的选项:
```{r fig.width=10/2.54, fig.height=10/2.54, out.width="80%"}
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)

当输出结果为HTML结果或者LaTeX转换的PDF时, 只要两个图形的总宽度小于页面宽度, 两个连续的图形就可以左右并列放置。 Word不支持这种功能。 例如:
```{r, echo=FALSE, fig.width=10/2.54, fig.height=10/2.54, out.width="45%"}
curve(exp(-0.1*x)*sin(x), 0, 2*pi)
abline(h=0, lty=3)
curve(exp(-0.1*x)*cos(x), 0, 2*pi)
abline(h=0, lty=3)
```
结果为


22.6.2.2 图形结果选择
用fig.keep=选项可以选择保留哪些R代码生成的图。 缺省是fig.keep='high', 即保留每个高级图形函数的结果图形, 低级图形函数对高级图形函数的更改不单独保存而汇总到高级图形函数结果中。 如
par(mar = c(3, 3, 0.1, 0.1))
plot(1:10, ann = FALSE, las = 1)
text(5, 9, "Testing low level graphics")

其中text()函数的结果与高级图形函数plot()的结果一起显示。
fig.keep还可以取:all, 会把低级图形函数修改后的结果单独保存; last, 仅保留最后一个图形;first, 仅保留第一个图; none, 所有图都不显示出来。
22.6.3 缓存(cache)选项
当R Markdown文章比较长,包含的R代码比较多, 或者代码段运行需要比较长时间时, 反复编译整篇文章会造成不必要的计算, 因为有些代码段并没有修改, 依赖的数据也没有改变。 knitr提供了缓存功能, 代码段选项cache=TRUE对代码段打开缓存, 允许暂存上次运行的结果(包括文本结果和图形) 而不需要重复运行代码段。 当代码段被修改时, 缓存被放弃, 编译时重新运行代码段。
缓存这种功能需要慎重使用, 免得错误地使用了旧的结果。 当后面的代码段需要使用前面代码段结果时, 如果前面结果改了, 后面的代码段就不能使用缓存的结果而必须重新计算。 为此, 在后面的代码段中应该加上dependson=选项, 比如dependson=c('codeA', 'codeB'), 其中codeA和codeB是前面的缓存了的代码段的标签, 其结果会用在本代码段中。 也可以使用代码段选项autodep=TRUE, knitr试图自动确定前后代码段之间的依赖关系, 每当前面的代码段改变时, 后面的用到其结果代码段也自动重新计算而不使用缓存的旧结果。
建议仅对计算一次需要较长时间的代码段使用缓存功能, 后面依赖于其结果的代码一定要加上dependson=选项。 建议代码段尽可能有标签,这样在编译失败时能马上看出失败的地点。
为了保险起见, 可以尽量不使用缓存功能, 而是用save()功能将需要长时间结算的结果保存下来, 用load()载入然后输出到结果文档中。
22.7 章节目录链接问题
对于英文文件, R Markdown基于的pandoc软件可以自动从标题生成适当的链接标签, 将HTML输出或者PDF输出设置属性toc: true后可以生成可点击的章节目录。 但是,目前Pandoc对于中文文件的支持差一些, 所以中文文件要自动生成可点击的目录, 需要在每个标题行的末尾,空格后添加{#label}, 其中label是自己指定的标签内容, 但是建议仅使用英文字母、数字、减号。 如
### 第三章第一节标题 {#c3-s1-int}
如果希望某个标题不参与自动编号, 可以在标题末尾空格之后加上{-}标记。
22.8 数学公式
22.8.1 在Markdown中输入数学公式
原始的Markdown格式并不支持数学公式。 Pandoc扩展的markdown格式提供了对数学公式的支持, 可以在Markdown文件中插入LaTeX格式的数学公式。 虽然不能提供所有的LaTeX公式能力, 但是常用的数学公式还是能做得很好, 转换到HTML、docx都可以得到正常显示的公式。
用RStudio软件编译Markdown文件,可以在其中插入LaTeX格式的数学公式, 编译成HTML或者docx格式后都可以正常显示数学公式, 在另外安装的LaTeX编译器的支持下也可以将.Rmd格式编译LaTeX格式然后再转换为PDF格式, 这种方法对数学公式的支持会更完善。
关于数学公式的软件设置参见下面设置部分的内容。
22.8.2 数学公式类别
数学公式公式分为行内公式和独立公式。 行内公式和段落的文字混排, 写在两个美元符号$中间,或者\(和\)之间。 例如$f(x)=\frac{1}{2} \int_0^1 \sin^2 (t x) dt$变成 。 开头的$后面不能紧跟着空格, 结尾的$不能紧跟在空格后面。
独立公式写在成对的美元符号中间,或者\[和\]之间。 例如:
$$
f(x) = \frac{1}{2} \sum_{j=1}^\infty \int_0^1 \sin^2(j t x) dt .
$$
显示为
22.8.3 基本功能
在数学公式中, 用下划线表示下标, 比如$x_1$结果为。 用^表示上标, 如$x^2$结果为。 上下标都有,如$x_1^2$结果为。
公式中用大括号表示一个整体, 比如$x^(1)$不能得到, 需要用$x^{(1)}$。
公式中用反斜杠开始一个命令, 命令仅包含字母而不能包含数字, 数字只能作为参数。 如$\frac{1}{2}$和$\frac12$都可以生成。 类似的命令如$\sqrt{2}$为。
希腊字母都有对应的命令, 如$\alpha$为, $\Sigma$为。
常用数学函数有自己的命令, 如$\sin x$变成, $\exp (x)$为。
圆括号与方括号可以直接使用, 绝对值符号用|, 如$|x|$变成。 但是,大括号必须写成\{和\}的形式, 如$\exp\{-\frac12 x^2\}$变成。
为了使得括号能够与括号内部的内容等高, 可以用\left和\right命令进行修饰, 如
$$
\phi(x) = \frac{1}{\sqrt{2\pi}} \exp\left\{ \frac{1}{2} x^2 \right\}
$$
变成
注意\left``\right
求和如$\sum_{i=1}^n x_i$变成。 乘积如$\prod_{i=1}^n x_i$变成。 积分如$\int_0^1 f(x) dx$变成。
22.8.4 修饰符
$f'(x)$显示为, 表示导数; $f''(x)$显示为, 表示二阶导数。 顺便说一句, 偏导数写法如$\frac{\partial f(x,t)}{\partial x}$, 显示为。
的写法是$\bar{x}$。 的写法是$\overline{\text{span}}$。 的写法是$\hat{x}$。 的写法是$\tilde{x}$。 的写法是$\vec{x}$。
22.8.5 对齐与矩阵
为了产生对齐的公式, 在独立公式中使用aligned环境。 公式中的环境以\begin{环境名}开始, 以\end{环境名}结束, 用\\表示换行,用&表示一个上下对齐位置。 如
$$
\begin{aligned}
f(x) =& \sum_{k=0}^\infty \frac{1}{k!} x^k \\
=& e^x
\end{aligned}
$$
转化成
可以用pmatrix环境制作写在圆括号中的矩阵, 用bmatrix环境制作写在方括号中的矩阵, 用vmatrix制作写在绝对值号中的矩阵,如
列向量、行向量也可以用这种办法制作。
22.8.6 特殊字体
数学公式中的单词、文字必须用\text{...}保护,比如
$$
\text{CV} = \frac{S}{\bar x} \times 100 \%
$$
变成
上例中如果不用\text{}
有时用粗体表示向量或者矩阵, 用\boldsymbol{...}说明。如
$$
\boldsymbol{v} = (v_1, v_2)^T
$$
变成
美术体英文字母用\mathcal{...}, 如写法为$\mathcal{A, B, C}$。
手写花体字母用\mathscr{...}, 如写法为$\mathscr{B, C, F, G}$。
22.9 其它编程语言引擎
Rmd文件中除了R代码段以外, 还可以插入Rcpp、Python、Julia、SQL等许多编程语言的代码段, 常用编程语言还可以与R代码段进行信息交换。
22.10 交互内容
在Rmd生成HTML结果时, 可以在结果中包含允许读者交互操作的内容, 比如, 用户修改模型参数, 使得模型报表、图形交互地改变。 有两种方法可以实现交互:
- HTML小程序(widgets), 由R扩展包htmlwidgets实现, 利用JavaScript函数库进行交互。 在这一功能基础上有一些派生的扩展包, 如DT,leaflet, dygraph。
- 利用shiny框架,这也是一个R扩展包, 交互功能由R的一个会话驱动。 Rmd文件的YAML元数据中需要设置
runtime: shiny。
22.11 属性设置
22.11.1 YAML元数据
可以在RStudio软件中编辑markdown文件与Rmarkdown文件, RStudio的markdown支持来自knitr、rmarkdown、bookdown扩展包和pandoc软件, .Rmd文件支持一些特殊的文件设置, 这些设置写在markdown文件和.Rmd文件的开头位置, 用三个减号组成的行作为开始标记与结束标记, 称为YAML元数据块(YAML meta data block), 块后面必须用空行分隔。 元数据块中可以用"设置属性名: 设置属性值"的办法设置属性, 用缩进表示属性内容,用上下对齐的行表示多项列表。 常用属性有title(标题)、author(作者)、date(日期)、output_format(输出格式)等,如
---
title: "临时测试"
author: "李东风"
date: "2016年7月6日"
---
这三个设置会出现在转换后结果的标题部分。 RStudio的中文支持还是有时出现问题, 如果出现涉及到YAML的错误, 先将中文内容替换为英文试一试。
因为冒号:在属性设置中有特殊意义, 属性设置值如果含有冒号, 需要把整个属性值两边用单撇号界定。
属性值可以是列表或多项,例如:
---
title: 'This is the title: it contains a colon'
author:
- name: Author One
affiliation: University of Somewhere
- name: Author Two
affiliation: University of Nowhere
tags: [nothing, nothingness]
abstract: |
This is the abstract.
It consists of two paragraphs.
---
此例中有title、author、tags、abstract四个属性。 author属性包含两个作者, 每个作者又有name和affiliation两个属性。 tags属性是一个两项的列表。 abstract属性用管道符号|表示开头,不需要结束标志,内容缩进。
22.11.2 输出格式
.Rmd文件开头的YAML元数据中, 属性output选择输出的格式, 如
html_document是HTML输出;pdf_document是PDF输出,通过系统中另外安装LaTeX编译系统转换;word_document是docx格式的Word文件输出,等等。
输出格式指定如:
output:
html_document: default
word_document: default
pdf_document: default
其中default表示该输出格式完全使用默认设置。 在输出格式没有定制设置时必须有default指定。
22.11.3 输出格式设置
在每种输出格式后面还可以继续添加该输出特有属性。 如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
pdf_document:
toc: true
22.11.4 目录设置
输出格式的toc: true选项指定自动生成目录, HTML输出、PDF输出、Word输出都支持此功能。 见上例。
output:
html_document:
toc: true
toc_depth: 2
上例中,html_document是output的属性, 隶属关系用缩进表示; html_document又有自己的属性toc和toc_depth, 隶属关系用缩进表示。 属性toc: true表示要自动生成可点击的目录。 输出格式的属性toc_depth是目录包含的章节层级数。
对html_document输出, 属性toc_float: true使得生成的文档在左侧显示一个目录导览窗格。 而toc_float属性又可以指定一些属性,隶属关系用缩进表示。 toc_float的属性collapse: true表示仅展开章节第一层级, smooth_scroll: true使得通过导览窗格跳跃时页面有平滑滚动过程显示。 用如:
output:
html_document:
toc: true
toc_float:
collapse: true
smooth_scroll: true
22.11.5 章节自动编号
输出格式的属性number_sections为true可以自动对章节编号。 HTML输出与PDF输出都支持此功能。
在章节自动编号时, 如果不是利用bookdown包而是基于基本的R Markdown, 文中的分节最高层级最好用一个井号, 对应于节, 如果用两个井号, 编号会变成0.1,0.2这样。
22.11.6 Word输出章节自动编号及模板功能
Word文件不能自动编号, 解决办法是生成适当的模板文件, 如wordstyle.docx, 然后在Rmd文件的元数据部分为word_document输出增加reference_docx选项,如:
output:
html_document:
toc: true
number_sections: true
word_document:
toc: true
reference_docx: wordstyle.docx
这样,新编译的Rmd文件就可以采用wordstyle.docx的格式设置, 比如章节自动编号等。 目前目录标题还是英文, 需要在结果中人为地修改为中文。 一个样例模板下载如下: wordstyle.docx
22.11.7 HTML特有输出格式设置
对于html_document输出类型, 可以用theme属性设置一个主题, 取值如default, cerulean, journal, flatly, darkly, readable, spacelab, united, cosmo, lumen, paper, sandstone, simplex, yeti。
用highlight属性设置程序语言语法高亮样式, 可取值有default, tango, pygments, kate, monochrome, espresso, zenburn, haddock, and textmate。 用null表示取消语法高亮。
可以用css属性指定一个自定义的CSS样式表文件。 如果希望完全用自己的样式代替原有样式, 可以设置theme: null。
code_folding属性设置HTML结果中代码折叠选项, 取值hide可以隐藏代码, 但读者通过选项可见。 取值show可以显示代码, 但读者通过选项可隐藏代码显示。
22.11.8 关于数学公式支持的设置
Rmd格式支持数学公式, 在生成的HTML、Word、PDF中都可以正常显示数学公式。
以HTML为输出时, 会使用MathJax库显示数学公式。 这是一个用于在浏览器中显示数学公式的Javascript程序库, 显示效果很好, 还支持多种显示实现方式, 支持包括LaTeX在内的多种数学公式输入方法。
MathJax库很大, 所以一般是从其网站按需远程调用的, 但是远程调用MathJax库在网络不畅通时会使得公式显示极为缓慢甚至无法显示, 所以Rmd允许将MathJax本地化。 在.Rmd文件头部YAML元数据的某种HTML输出格式的属性中, 设置属性mathjax: local和就可以使得MathJax库被放在生成的HTML的一个下层目录中。 设置如
output:
html_document:
toc: true
self_contained: false
mathjax: local
注意设置mathjax: local同时必须设置self_contained: false。 在不使用本地MathJax副本时, 可以设置self_contained: true, 这使得图形文件、JavaScript代码等依赖项也打包在生成的单一HTML文件中, 如果设为false, 这些依赖文件会存放在单独文件中。 可以用lib_dir属性指定一个子目录用来存放这些依赖文件, 多个Rmd文件可以共用同一个lib_dir值。
将MathJax用mathjax: local属性本地化有明显的缺点。 这时,每个Rmd项目都需要一个MathJax库副本, 使得文件备份变得很麻烦。 下面的设置方法可以令多个Rmd项目共享一个共同的本地MathJax库。
22.11.9 输出设置文件
如果一个项目包含多个.Rmd文件, 每个文件单独用YAML元数据进行设置比较繁琐, 修改时也很麻烦。 可以在项目目录中增加一个_output.yml文件, 其中包含所有.Rmd文件共用的output属性的设置, 各个.Rmd文件还可以有自己单独的output属性, .Rmd文件YAML元数据中的属性优先级高于共同设置的属性。
例如,_output.yml文件内容如下:
html_document:
toc: yes
number_sections: yes
mathjax: "../../MathJax/MathJax.js"
includes:
in_header: "_header.html"
word_document:
toc: yes
reference_docx: wordstyle.docx
pdf_document:
includes:
in_header: preamble.tex
latex_engine: xelatex
上面设置了使用本地硬盘的MathJax库, 位于项目目录的上两层目录中的MathJax子目录中。 这样可以使得多个项目共享一个MathJax库。 将生成的结果当作网站发布时, 只要将MathJax库也安装到项目在网站的目录的上两层的MathJax子目录中就可以。 其中_header.html内容如下,是关于MathJax具体的一些设置:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
jax: ["input/TeX","output/SVG"],
extensions: ["tex2jax.js","MathMenu.js","MathZoom.js"],
TeX: {
extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
}
});
</script>
注意, _output.yml文件都是输出设置, 所以不能再有output属性,所以下面的_output.yml写法是不正确的:
output:
html_document:
toc: yes
22.12 LaTeX和PDF输出
Rmd文件的pdf_document输出类型是先转换为LaTeX文件, 再借助计算机系统中另外安装的LaTeX编译程序转换为PDF。 需要在系统中安装一个TeX编译器, MS Windows下有MikTeX软件包或者CTEX软件包。 如果仅在R Markdown文件中使用LaTeX功能, 可以安装谢益辉的TinyTeX软件包, 优点是直接用R命令就可以安装, 更新也由R自动进行,不需要用户干预。
许多LaTeX相关的YAML元数据不是设置在输出属性中, 而是设置为文件的顶级元数据。 如
其中属性fontsize和geometry都是LaTeX选项, 但是没有作为output--pdf_document的属性, 而是作为Rmd文件的顶级元数据属性。
用属性documentclass指定LaTeX文档类型, 比如article是论文格式, book是图书格式。 ctexart和ctexbook是适用于中文的格式。
fontsize是正文字体大小, 可取10pt, 11pt, 12pt, 其中10pt是缺省大小。
geometry用来指定geometry包的参数。
默认的LaTeX编译引擎是pdfLaTeX。 可以在pdf_document输出的属性中设置latex_engine: xelatex将引擎替换成xeLaTeX。 xeLaTeX的优点是支持UTF8编码,可以使用系统中现有字体, 而我们在写中文的R Markdown文档时必须使用UTF-8编码。
Rmd文件中的文献引用可以由pandoc软件执行, 但是在用LaTeX转换PDF时, 可以指定用一个LaTeX引用包, 如:
---
output:
pdf_document:
latex_engine: xelatex
citation_package: natbib
---
为了自动生成目录并自动为章节编号, 仍在pdf_document的属性中指定toc: true和number_section: true。
在使用bookdown管理Rmd文件时, 文献引用、目录、章节编号方式有另外的指定办法以及默认规则。
为了能够检查转换过程中的错误, 可以用pdf_document的属性keep_tex: true, 保留作为中间结果的.tex文件, 人工检查其中的错误。
可以在pdf_document输出的属性中指定若干个.tex文件插入到LaTeX文档的导言、正文最前面、正文最后后面,如
---
output:
pdf_document:
latex_engine: xelatex
keep_tex: true
citation_package: natbib
toc: true
number_sections: true
includes:
in_header: preamble.tex
before_body: doc-prefix.tex
after_body: doc-suffix.tex
---
preamble.tex主要用来载入额外的LaTeX包以及定义新的命令, 一个preamble.tex的例子如下
不支持百分号,只能去看原文档了。
http://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/index.html
22.13 生成期刊文章
节22.12的办法可以用来生成LaTeX然后转换为PDF, 可以用来撰写学位论文和期刊论文。 但是学位论文和期刊论文都有比较严格的格式要求, 用节22.12的一般方法需要对LaTeX比较熟悉才能达到格式要求。
用R扩展包rticles可以比较容易地将Rmd文件转换成期刊可接受的LaTeX和PDF格式。 见https://bookdown.org/yihui/rmarkdown/journals.html。 扩展包中对一些常见期刊提供了模板。
首先要安装rticles扩展包,命令为
install.packages("rticles")
为了生成新的论文源文件, 在RStudio中, 用"File -- New File -- R Markdown -- from Template"菜单, 从列出的文章模板中选一个。
杂志投稿的Rmd模板是用许多元数据来规定格式的。 用户可以修改其中的标题、作者、作者单位等信息。
因为rticlels的输出只有PDF, 所以必要时可以在Rmd源文件中直接使用LaTeX命令, 但如果Rmd本身可以完成时尽可能用Rmd的功能。
因为定理、图表自动标号和索引功能是由bookdown包提供的, 而rticles的输出类型实际是rmarkdown::pdf_docment, 所以可以联合使用bookdown与rticles,如
output:
bookdown::pdf_book
base_format: rticles::peerj_article
其中peerj_article可以替换成rticles提供的其它格式。
如果自己需要的模板rticles没有提供, 可以自己设法定义模板, 参见https://bookdown.org/yihui/rmarkdown/document-templates.html。
22.14 附录:经验与问题
22.14.1 Word模板制作
如果有合适的Word格式样例, 可以在YAML元数据的word_document的属性中, 设置reference_docs属性指向该模板文件。
为了制作Word模板, 不应该从头开始, 而是在没有模板的情况下从Rmd文件转换生成一个Word文件, 将其作为模板文件的基础进行修改。 在修改过程中, 应该制作过程的备份,以便修改错误时能退回上一个版本。
如果文章的大标题样式不是"标题", 将样式改为"标题"以免在后续的自动编号过程中参与编号。 修改的方法是选中大标题, 然后在Word软件主菜单的"开始--样式"选择框中选中"标题", 就可以设置其样式。
Word的目录是与"标题1"同级的, 这样会在自动编号时参与编号; 为此, 选中"Contents", 然后在主菜单的"开始--样式"选择框中, 找到突出显示的"TOC标题", 右键单击"修改", 在弹出的对话框中将"样式基准"从"标题1"改为"标题", 并在同一对话框中将适当调整样式, 如字体类型、大小、颜色、是否居中。 改完后保存并保存一个副本。
如果需要修改"标题","作者","日期","标题1"等等的字体、大小、颜色、对齐方式, 可以选中该部分,并在"样式"中邮件单击相应的样式,选择"修改"进行修改, 保存样式文件并试验Rmd文件是否正确地利用了修改的样式。
为了实现自动编号, 先在正文中选中一个一级标题(不能是目录标题), 从Word的主菜单栏找到"开始------段落------多级列表------定义新的多级列表", 在打开的对话框中点击"更多"选项, 逐一地选择"单击要修改的级别", 将级别1、2、3等分别修改, 主要是修改"将级别链接到样式"使得"级别1"与"标题1"对应, "级别2"与"标题2"对应,等等。 注意这个修改要一次性完成, 不能保存了文件后再次定义新的多级列表。
修改模板文件的页边距也会使得利用其为模板的Rmd文件转换结果被修改。 为了修改模板文件的页边距, 在主菜单"布局------页边距------自定义页边距"弹出的对话框中修改。
生成的目录的标题内容是"Table of Contents", 目前只能对Rmd输出的docx文件直接修改, 修改模板文件的标题内容并不能使得Rmd输出被修改。
参考:Richard Layton的网站文章 https://rmarkdown.rstudio.com/articles_docx.html。
22.14.2 数学公式设置补充
如果不使用RStudio, R扩展包rmarkdown的markdownToHTML()函数可以把含有数学公式的内容转换成可显示公式的HTML文件, R扩展包knitr的knit2html()也可以实现此功能。 用rmarkdown扩展包的markdownToHTML()函数生成的含有数学公式的内容。
单独使用pandoc软件时, 也可以用普通文本编辑器在Markdown文件中输入LaTeX格式的数学公式, 然后用pandoc软件转化为带有数学公式的docx文件, 不需要额外选项。 但是,为了能够在转换的HTML文件中正常显示数学公式, 需要在运行Pandoc时增加运行选项--maxjax,如
pandoc --mathjax -s -o test.html test.md
经试验,这样转化的HTML文件可以在Firefox以及Microsoft的 Edge浏览器和Internet Explorer浏览器中正常显示数学公式。 如果公式中的中文显示不正常, 对显示的公式右键单击弹出选项菜单, 选择"Math Settings--Math Renderer--SVG"或者"HTML-CSS"。
References
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2019. R Markdown: The Definitive Guide. CRC Press. https://bookdown.org/yihui/rmarkdown/.