RMarkdown/Bookdown 排版示例
本文无意全文翻译 RMarkdown/Bookdown 的使用方法,只是简单的复制,详细内容请参考页面:
以下为全文复制 https://bookdown.org/yihui/bookdown/components.html ,有改动。
This chapter demonstrates the syntax of common components of a book written in bookdown, including code chunks, figures, tables, citations, math theorems, and equations. The approach is based on Pandoc, so we start with the syntax of Pandoc’s flavor of Markdown.
Markdown syntax
In this section, we give a very brief introduction to Pandoc’s Markdown. Readers who are familiar with Markdown can skip this section. The comprehensive syntax of Pandoc’s Markdown can be found on the Pandoc website http://pandoc.org.
Block-level elements
Section headers can be written after a number of pound signs, e.g.,
# First-level header
## Second-level header
### Third-level header
If you do not want a certain heading to be numbered, you can add {-}
after the heading, e.g.,
# Preface {-}
Unordered list items start with *
, -
, or +
, and you can nest one list within another list by indenting the sub-list by four spaces, e.g.,
- one item
- one item
- one item
- one item
- one item
The output is:
- one item
- one item
- one item
Ordered list items start with numbers (the rule for nested lists is the same as above), e.g.,
1. the first item
2. the second item
3. the third item
The output does not look too much different with the Markdown source:
- the first item
- the second item
- the third item
Blockquotes are written after >
, e.g.,
> "I thoroughly disapprove of duels. If a man should challenge me,
I would take him kindly and forgivingly by the hand and lead him
to a quiet place and kill him."
>
> --- Mark Twain
The actual output (we customized the style for blockquotes in this book):
“I thoroughly disapprove of duels. If a man should challenge me,
I would take him kindly and forgivingly by the hand and lead him
to a quiet place and kill him.”
— Mark Twain
Plain code blocks can be written after three or more backticks, and you can also indent the blocks by four spaces, e.g.,
```
This text is displayed verbatim / preformatted
```
Or indent by four spaces:
This text is displayed verbatim / preformatted
Math expressions
Inline LaTeX equations can be written in a pair of dollar signs using the LaTeX syntax, e.g., $f(k) = {n \choose k} p^{k} (1-p)^{n-k}$
(actual output: \(f(k)={n \choose k}p^{k}(1-p)^{n-k}\)); math expressions of the display style can be written in a pair of double dollar signs, e.g., $$f(k) = {n \choose k} p^{k} (1-p)^{n-k}$$
, and the output looks like this:
\[f\left(k\right)=\binom{n}{k}p^k\left(1-p\right)^{n-k}\]
You can also use math environments inside $ $
or $$ $$
, e.g.,
$$\begin{array}{ccc}
x_{11} & x_{12} & x_{13}\\
x_{21} & x_{22} & x_{23}
\end{array}$$
\[\begin{array}{ccc}
x_{11} & x_{12} & x_{13}\\
x_{21} & x_{22} & x_{23}
\end{array}\]
$$X = \begin{bmatrix}1 & x_{1}\\
1 & x_{2}\\
1 & x_{3}
\end{bmatrix}$$
\[X = \begin{bmatrix}1 & x_{1}\\
1 & x_{2}\\
1 & x_{3}
\end{bmatrix}\]
$$\Theta = \begin{pmatrix}\alpha & \beta\\
\gamma & \delta
\end{pmatrix}$$
\[\Theta = \begin{pmatrix}\alpha & \beta\\
\gamma & \delta
\end{pmatrix}\]
$$\begin{vmatrix}a & b\\
c & d
\end{vmatrix}=ad-bc$$
\[\begin{vmatrix}a & b\\
c & d
\end{vmatrix}=ad-bc\]
Markdown extensions by bookdown
Although Pandoc’s Markdown is much richer than the original Markdown syntax, it still lacks a number of things that we may need for academic writing. For example, it supports math equations, but you cannot number and reference equations in multi-page HTML or EPUB output. We have provided a few Markdown extensions in bookdown to fill the gaps.
Number and reference equations
To number and refer to equations, put them in the equation environments and assign labels to them using the syntax (\#eq:label)
, e.g.,
\begin{equation}
f\left(k\right) = \binom{n}{k} p^k\left(1-p\right)^{n-k}
(\#eq:binom)
\end{equation}
It renders the equation below:
\[\begin{equation}
f\left(k\right)=\binom{n}{k}p^k\left(1-p\right)^{n-k} \tag{D.1}
\end{equation}\]
You may refer to it using \@ref(eq:binom)
, e.g., see Equation (D.1).
Equation labels must start with the prefix eq:
in bookdown. All labels in bookdown must only contain alphanumeric characters, :
, -
, and/or /
. Equation references work best for LaTeX/PDF output, and they are not well supported in Word output or e-books. For HTML output, bookdown can only number the equations with labels. Please make sure equations without labels are not numbered by either using the equation*
environment or adding \nonumber
or \notag
to your equations. The same rules apply to other math environments, such as eqnarray
, gather
, align
, and so on (e.g., you can use the align*
environment).
We demonstrate a few more math equation environments below. Here is an unnumbered equation using the equation*
environment:
\begin{equation*}
\frac{d}{dx}\left( \int_{a}^{x} f(u)\,du\right)=f(x)
\end{equation*}
\[\begin{equation*}
\frac{d}{dx}\left( \int_{a}^{x} f(u)\,du\right)=f(x)
\end{equation*}\]
Below is an align
environment (D.2):
\begin{align}
g(X_{n}) &= g(\theta)+g'({\tilde{\theta}})(X_{n}-\theta) \notag \\
\sqrt{n}[g(X_{n})-g(\theta)] &= g'\left({\tilde{\theta}}\right)
\sqrt{n}[X_{n}-\theta ] (\#eq:align)
\end{align}
\[\begin{align}
g(X_{n}) &= g(\theta)+g'({\tilde{\theta}})(X_{n}-\theta) \notag \\
\sqrt{n}[g(X_{n})-g(\theta)] &= g'\left({\tilde{\theta}}\right)
\sqrt{n}[X_{n}-\theta ] \tag{D.2}
\end{align}\]
You can use the split
environment inside equation
so that all lines share the same number (D.3). By default, each line in the align
environment will be assigned an equation number. We suppressed the number of the first line in the previous example using \notag
. In this example, the whole split
environment was assigned a single number.
\begin{equation}
\begin{split}
\mathrm{Var}(\hat{\beta}) & =\mathrm{Var}((X'X)^{-1}X'y)\\
& =(X'X)^{-1}X'\mathrm{Var}(y)((X'X)^{-1}X')'\\
& =(X'X)^{-1}X'\mathrm{Var}(y)X(X'X)^{-1}\\
& =(X'X)^{-1}X'\sigma^{2}IX(X'X)^{-1}\\
& =(X'X)^{-1}\sigma^{2}
\end{split}
(\#eq:var-beta)
\end{equation}
\[\begin{equation}
\begin{split}
\mathrm{Var}(\hat{\beta}) & =\mathrm{Var}((X'X)^{-1}X'y)\\
& =(X'X)^{-1}X'\mathrm{Var}(y)((X'X)^{-1}X')'\\
& =(X'X)^{-1}X'\mathrm{Var}(y)X(X'X)^{-1}\\
& =(X'X)^{-1}X'\sigma^{2}IX(X'X)^{-1}\\
& =(X'X)^{-1}\sigma^{2}
\end{split}
\tag{D.3}
\end{equation}\]
Theorems and proofs
Theorems and proofs are commonly used in articles and books in mathematics. However, please do not be misled by the names: a “theorem” is just a numbered/labeled environment, and it does not have to be a mathematical theorem (e.g., it can be an example irrelevant to mathematics). Similarly, a “proof” is an unnumbered environment. In this section, we always use the general meanings of a “theorem” and “proof” unless explicitly stated.
In bookdown, the types of theorem environments supported are in Table D.1. To write a theorem, you can use the syntax below:
```{theorem}
Here is my theorem.
```
Table D.1: Theorem environments in bookdown.
theorem |
Theorem |
thm |
lemma |
Lemma |
lem |
corollary |
Corollary |
cor |
proposition |
Proposition |
prp |
conjecture |
Conjecture |
cnj |
definition |
Definition |
def |
example |
Example |
exm |
exercise |
Exercise |
exr |
To write other theorem environments, replace ```{theorem}
with other environment names in Table D.1, e.g., ```{lemma}
.
A theorem can have a name
option so its name will be printed, e.g.,
```{theorem, name="Pythagorean theorem"}
For a right triangle, if $c$ denotes the length of the hypotenuse
and $a$ and $b$ denote the lengths of the other two sides, we have
$$a^2 + b^2 = c^2$$
```
If you want to refer to a theorem, you should label it. The label can be written after ```{theorem
, e.g.,
```{theorem, label="foo"}
A labeled theorem here.
```
The label
option can be implicit, e.g., the following theorem has the label bar
:
```{theorem, bar}
A labeled theorem here.
```
After you label a theorem, you can refer to it using the syntax \@ref(prefix:label)
. See the column Label Prefix
in Table D.1 for the value of prefix
for each environment. For example, we have a labeled and named theorem below, and \@ref(thm:pyth)
gives us its theorem number D.1:
```{theorem, pyth, name="Pythagorean theorem"}
For a right triangle, if $c$ denotes the length of the hypotenuse
and $a$ and $b$ denote the lengths of the other two sides, we have
$$a^2 + b^2 = c^2$$
```
Theorem D.1 (Pythagorean theorem) For a right triangle, if \(c\) denotes the length of the hypotenuse
and \(a\) and \(b\) denote the lengths of the other two sides, we have
\[a^2 + b^2 = c^2\]
The proof environments currently supported are proof
, remark
, and solution
. The syntax is similar to theorem environments, and proof environments can also be named. The only difference is that since they are unnumbered, you cannot reference them.
We have tried to make all these theorem and proof environments work out of the box, no matter if your output is PDF, HTML, or EPUB. If you are a LaTeX or HTML expert, you may want to customize the style of these environments anyway (see Chapter ??). Customization in HTML is easy with CSS, and each environment is enclosed in <div></div>
with the CSS class being the environment name, e.g., <div class="lemma"></div>
. For LaTeX output, we have predefined the style to be definition
for environments definition
, example
, and exercise
, and remark
for environments proof
and remark
. All other environments use the plain
style. The style definition is done through the \theoremstyle{}
command of the amsthm package.
Theorems are numbered by chapters by default. If there are no chapters in your document, they are numbered by sections instead. If the whole document is unnumbered (the output format option number_sections = FALSE
), all theorems are numbered sequentially from 1, 2, …, N. LaTeX supports numbering one theorem environment after another, e.g., let theorems and lemmas share the same counter. This is not supported for HTML/EPUB output in bookdown. You can change the numbering scheme in the LaTeX preamble by defining your own theorem environments, e.g.,
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
When bookdown detects \newtheorem{theorem}
in your LaTeX preamble, it will not write out its default theorem definitions, which means you have to define all theorem environments by yourself. For the sake of simplicity and consistency, we do not recommend that you do this. It can be confusing when your Theorem 18 in PDF becomes Theorem 2.4 in HTML.
Theorem and proof environments will be hidden if the chunk option echo
is set to FALSE
. To make sure they are always shown, you may add the chunk option echo=TRUE
, e.g.,
```{theorem, echo=TRUE}
Here is my theorem.
```
Below we show more examples of the theorem and proof environments, so you can see the default styles in bookdown.
Definition D.1 The characteristic function of a random variable \(X\) is defined by
\[\varphi _{X}(t)=\operatorname {E} \left[e^{itX}\right], \; t\in\mathcal{R}\]
Example D.1 We derive the characteristic function of \(X\sim U(0,1)\) with the probability density function \(f(x)=\mathbf{1}_{x \in [0,1]}\).
\[\begin{equation*}
\begin{split}
\varphi _{X}(t) &= \operatorname {E} \left[e^{itX}\right]\\
& =\int e^{itx}f(x)dx\\
& =\int_{0}^{1}e^{itx}dx\\
& =\int_{0}^{1}\left(\cos(tx)+i\sin(tx)\right)dx\\
& =\left.\left(\frac{\sin(tx)}{t}-i\frac{\cos(tx)}{t}\right)\right|_{0}^{1}\\
& =\frac{\sin(t)}{t}-i\left(\frac{\cos(t)-1}{t}\right)\\
& =\frac{i\sin(t)}{it}+\frac{\cos(t)-1}{it}\\
& =\frac{e^{it}-1}{it}
\end{split}
\end{equation*}\]
Note that we used the fact
\(e^{ix}=\cos(x)+i\sin(x)\) twice.
Lemma D.1 For any two random variables \(X_1\), \(X_2\), they both have the same probability distribution if and only if
\[\varphi _{X_1}(t)=\varphi _{X_2}(t)\]
Theorem D.2 If \(X_1\), …, \(X_n\) are independent random variables, and \(a_1\), …, \(a_n\) are some constants, then the characteristic function of the linear combination \(S_n=\sum_{i=1}^na_iX_i\) is
\[\varphi _{S_{n}}(t)=\prod_{i=1}^n\varphi _{X_i}(a_{i}t)=\varphi _{X_{1}}(a_{1}t)\cdots \varphi _{X_{n}}(a_{n}t)\]
Proposition D.1 The distribution of the sum of independent Poisson random variables \(X_i \sim \mathrm{Pois}(\lambda_i),\: i=1,2,\cdots,n\) is \(\mathrm{Pois}(\sum_{i=1}^n\lambda_i)\).
Proof. The characteristic function of \(X\sim\mathrm{Pois}(\lambda)\) is \(\varphi _{X}(t)=e^{\lambda (e^{it}-1)}\). Let \(P_n=\sum_{i=1}^nX_i\). We know from Theorem D.2 that
\[\begin{equation*}
\begin{split}
\varphi _{P_{n}}(t) & =\prod_{i=1}^n\varphi _{X_i}(t) \\
& =\prod_{i=1}^n e^{\lambda_i (e^{it}-1)} \\
& = e^{\sum_{i=1}^n \lambda_i (e^{it}-1)}
\end{split}
\end{equation*}\]
This is the characteristic function of a Poisson random variable with the parameter
\(\lambda=\sum_{i=1}^n \lambda_i\). From Lemma
D.1, we know the distribution of
\(P_n\) is
\(\mathrm{Pois}(\sum_{i=1}^n\lambda_i)\).
Corollary D.1 The characteristic function of the sum of two independent random variables \(X_1\) and \(X_2\) is the product of characteristic functions of \(X_1\) and \(X_2\), i.e.,
\[\varphi _{X_1+X_2}(t)=\varphi _{X_1}(t) \varphi _{X_2}(t)\]
Exercise D.1 (Characteristic Function of the Sample Mean) Let \(\bar{X}=\sum_{i=1}^n \frac{1}{n} X_i\) be the sample mean of \(n\) independent and identically distributed random variables, each with characteristic function \(\varphi _{X}\). Compute the characteristic function of \(\bar{X}\).
Solution. Applying Theorem D.2, we have
\[\varphi _{\bar{X}}(t)=\prod_{i=1}^n \varphi _{X_i}\left(\frac{t}{n}\right)=\left[\varphi _{X}\left(\frac{t}{n}\right)\right]^n.\]
Text references
You can assign some text to a label and reference the text using the label elsewhere in your document. This can be particularly useful for long figure/table captions (Section D.4 and D.5), in which case you normally will have to write the whole character string in the chunk header (e.g., fig.cap = "A long long figure caption."
) or your R code (e.g., kable(caption = "A long long table caption.")
). It is also useful when these captions contain special HTML or LaTeX characters, e.g., if the figure caption contains an underscore, it works in the HTML output but may not work in LaTeX output because the underscore must be escaped in LaTeX.
The syntax for a text reference is (ref:label) text
, where label
is a unique label throughout the document for text
. It must be in a separate paragraph with empty lines above and below it. The paragraph must not be wrapped into multiple lines, and should not end with a white space. For example,
$(ref:foo)$ Define a text reference **here**.
Then you can use (ref:foo)
in your figure/table captions. The text can contain anything that Markdown supports, as long as it is one single paragraph. Here is a complete example:
A normal paragraph.
$(ref:foo)$ A scatterplot of the data `cars` using **base** R graphics.
```{r foo, fig.cap='(ref:foo)'}
plot(cars) # a scatterplot
```
Text references can be used anywhere in the document (not limited to figure captions). It can also be useful if you want to reuse a fragment of text in multiple places.
R code
There are two types of R code in R Markdown/knitr documents: R code chunks, and inline R code. The syntax for the latter is `r R_CODE`
, and it can be embedded inline with other document elements. R code chunks look like plain code blocks, but have {r}
after the three backticks and (optionally) chunk options inside {}
, e.g.,
```{r chunk-label, echo = FALSE, fig.cap = 'A figure caption.'}
1 + 1
rnorm(10) # 10 random numbers
plot(dist ~ speed, cars) # a scatterplot
```
To learn more about knitr chunk options, see @xie2015 or the web page http://yihui.name/knitr/options. For books, additional R code can be executed before/after each chapter; see before_chapter_script
and after_chapter_script
in Section ??.
\includegraphics[width=70%]{deepin-bible_files/figure-html/no-caption-1}
The disadvantage of typesetting figures in this way is that when there is not enough space on the current page to place a figure, it may either reach the bottom of the page (hence exceeds the page margin), or be pushed to the next page, leaving a large white margin at the bottom of the current page. That is basically why there are “floating environments” in LaTeX: elements that cannot be split over multiple pages (like figures) are put in floating environments, so they can float to a page that has enough space to hold them. There is also a disadvantage of floating things forward or backward, though. That is, readers may have to jump to a different page to find the figure mentioned on the current page. This is simply a natural consequence of having to typeset things on multiple pages of fixed sizes. This issue does not exist in HTML, however, since everything can be placed continuously on one single page (presumably with infinite height), and there is no need to split anything across multiple pages of the same page size.
If we assign a figure caption to a code chunk via the chunk option fig.cap
, R plots will be put into figure environments, which will be automatically labeled and numbered, and can also be cross-referenced. The label of a figure environment is generated from the label of the code chunk, e.g., if the chunk label is foo
, the figure label will be fig:foo
(the prefix fig:
is added before foo
). To reference a figure, use the syntax \@ref(label)
, where label
is the figure label, e.g., fig:foo
.
To take advantage of Markdown formatting within the figure caption, you will need to use text references (see Section D.2.4). For example, a figure caption that contains _italic text_
will not work when the output format is LaTeX/PDF, since the underscore is a special character in LaTeX, but if you use text references, _italic text_
will be translated to LaTeX code when the output is LaTeX.
If you want to cross-reference figures or tables generated from a code chunk, please make sure the chunk label only contains alphanumeric characters (a-z, A-Z, 0-9), slashes (/), or dashes (-).
The chunk option fig.asp
can be used to set the aspect ratio of plots, i.e., the ratio of figure height/width. If the figure width is 6 inches (fig.width = 6
) and fig.asp = 0.7
, the figure height will be automatically calculated from fig.width * fig.asp = 6 * 0.7 = 4.2
. Figure D.1 is an example using the chunk options fig.asp = 0.7
, fig.width = 6
, and fig.align = 'center'
, generated from the code below:
par(mar = c(4, 4, .1, .1))
plot(pressure, pch = 19, type = 'b')
\begin{figure}
{\includegraphics[width=90%]{deepin-bible_files/figure-html/pressure-plot-1}
}
\end{figure}
The actual size of a plot is determined by the chunk options fig.width
and fig.height
(the size of the plot generated from a graphical device), and we can specify the output size of plots via the chunk options out.width
and out.height
. The possible value of these two options depends on the output format of the document. For example, out.width = '30%'
is a valid value for HTML output, but not for LaTeX/PDF output. However, knitr will automatically convert a percentage value for out.width
of the form x%
to (x / 100) \linewidth
, e.g., out.width = '70%'
will be treated as .7\linewidth
when the output format is LaTeX. This makes it possible to specify a relative width of a plot in a consistent manner. Figure D.2 is an example of out.width = 70%
.
par(mar = c(4, 4, .1, .1))
plot(cars, pch = 19)
\begin{figure}
\includegraphics[width=70%]{deepin-bible_files/figure-html/cars-plot-1}
\end{figure}
If you want to put multiple plots in one figure environment, you must use the chunk option fig.show = 'hold'
to hold multiple plots from a code chunk and include them in one environment. You can also place plots side by side if the sum of the width of all plots is smaller than or equal to the current line width. For example, if two plots have the same width 50%
, they will be placed side by side. Similarly, you can specify out.width = '33%'
to arrange three plots on one line. Figure D.3 is an example of two plots, each with a width of 50%
.
par(mar = c(4, 4, .1, .1))
plot(pressure, pch = 19, type = 'b')
plot(cars, pch = 19)
\begin{figure}
\includegraphics[width=50%]{deepin-bible_files/figure-html/multi-plots-1} \includegraphics[width=50%]{deepin-bible_files/figure-html/multi-plots-2}
\end{figure}
Sometimes you may have certain images that are not generated from R code, and you can include them in R Markdown via the function knitr::include_graphics()
. Figure D.4 is an example of three knitr logos included in a figure environment. You may pass one or multiple image paths to the include_graphics()
function, and all chunk options that apply to normal R plots also apply to these images, e.g., you can use out.width = '33%'
to set the widths of these images in the output document.
knitr::include_graphics(rep('images/bookdown/knit-logo.png', 3))
\begin{figure}
\includegraphics[width=32.8%]{images/bookdown/knit-logo} \includegraphics[width=32.8%]{images/bookdown/knit-logo} \includegraphics[width=32.8%]{images/bookdown/knit-logo}
\end{figure}
There are a few advantages of using include_graphics()
:
- You do not need to worry about the document output format, e.g., when the output format is LaTeX, you may have to use the LaTeX command
\includegraphics{}
to include an image, and when the output format is Markdown, you have to use ![]()
. The function include_graphics()
in knitr takes care of these details automatically.
- The syntax for controlling the image attributes is the same as when images are generated from R code, e.g., chunk options
fig.cap
, out.width
, and fig.show
still have the same meanings.
include_graphics()
can be smart enough to use PDF graphics automatically when the output format is LaTeX and the PDF graphics files exist, e.g., an image path foo/bar.png
can be automatically replaced with foo/bar.pdf
if the latter exists. PDF images often have better qualities than raster images in LaTeX/PDF output. To make use of this feature, set the argument auto_pdf = TRUE
, or set the global option options(knitr.graphics.auto_pdf = TRUE)
to enable this feature globally in an R session.
- You can easily scale these images proportionally using the same ratio. This can be done via the
dpi
argument (dots per inch), which takes the value from the chunk option dpi
by default. If it is a numeric value and the chunk option out.width
is not set, the output width of an image will be its actual width (in pixels) divided by dpi
, and the unit will be inches. For example, for an image with the size 672 x 480, its output width will be 7 inches (7in
) when dpi = 96
. This feature requires the package png and/or jpeg to be installed. You can always override the automatic calculation of width in inches by providing a non-NULL value to the chunk option out.width
, or use include_graphics(dpi = NA)
.
Tables
For now, the most convenient way to generate a table is the function knitr::kable()
, because there are some internal tricks in knitr to make it work with bookdown and users do not have to know anything about these implementation details. We will explain how to use other packages and functions later in this section.
Like figures, tables with captions will also be numbered and can be referenced. The kable()
function will automatically generate a label for a table environment, which is the prefix tab:
plus the chunk label. For example, the table label for a code chunk with the label foo
will be tab:foo
, and we can still use the syntax \@ref(label)
to reference the table. Table D.2 is a simple example.
knitr::kable(
head(mtcars[, 1:8], 10), booktabs = TRUE,
caption = 'A table of the first 10 rows of the mtcars data.'
)
Table D.2: A table of the first 10 rows of the mtcars data.
Mazda RX4 |
21.0 |
6 |
160.0 |
110 |
3.90 |
2.620 |
16.46 |
0 |
Mazda RX4 Wag |
21.0 |
6 |
160.0 |
110 |
3.90 |
2.875 |
17.02 |
0 |
Datsun 710 |
22.8 |
4 |
108.0 |
93 |
3.85 |
2.320 |
18.61 |
1 |
Hornet 4 Drive |
21.4 |
6 |
258.0 |
110 |
3.08 |
3.215 |
19.44 |
1 |
Hornet Sportabout |
18.7 |
8 |
360.0 |
175 |
3.15 |
3.440 |
17.02 |
0 |
Valiant |
18.1 |
6 |
225.0 |
105 |
2.76 |
3.460 |
20.22 |
1 |
Duster 360 |
14.3 |
8 |
360.0 |
245 |
3.21 |
3.570 |
15.84 |
0 |
Merc 240D |
24.4 |
4 |
146.7 |
62 |
3.69 |
3.190 |
20.00 |
1 |
Merc 230 |
22.8 |
4 |
140.8 |
95 |
3.92 |
3.150 |
22.90 |
1 |
Merc 280 |
19.2 |
6 |
167.6 |
123 |
3.92 |
3.440 |
18.30 |
1 |
If you want to put multiple tables in a single table environment, wrap the data objects (usually data frames in R) into a list. See Table D.3 for an example. Please note that this feature is only available in HTML and PDF output.
knitr::kable(
list(
head(iris[, 1:2], 3),
head(mtcars[, 1:3], 5)
),
caption = 'A Tale of Two Tables.', booktabs = TRUE
)
Table D.3: A Tale of Two Tables.
|
Mazda RX4 |
21.0 |
6 |
160 |
Mazda RX4 Wag |
21.0 |
6 |
160 |
Datsun 710 |
22.8 |
4 |
108 |
Hornet 4 Drive |
21.4 |
6 |
258 |
Hornet Sportabout |
18.7 |
8 |
360 |
|
When you do not want a table to float in PDF, you may use the LaTeX package longtable, which can break a table across multiple pages. To use longtable, pass longtable = TRUE
to kable()
, and make sure to include \usepackage{longtable}
in the LaTeX preamble (see Section ?? for how to customize the LaTeX preamble). Of course, this is irrelevant to HTML output, since tables in HTML do not need to float.
knitr::kable(
iris[1:55, ], longtable = TRUE, booktabs = TRUE,
caption = 'A table generated by the longtable package.'
)
Table D.4: A table generated by the longtable package.
5.1 |
3.5 |
1.4 |
0.2 |
setosa |
4.9 |
3.0 |
1.4 |
0.2 |
setosa |
4.7 |
3.2 |
1.3 |
0.2 |
setosa |
4.6 |
3.1 |
1.5 |
0.2 |
setosa |
5.0 |
3.6 |
1.4 |
0.2 |
setosa |
5.4 |
3.9 |
1.7 |
0.4 |
setosa |
4.6 |
3.4 |
1.4 |
0.3 |
setosa |
5.0 |
3.4 |
1.5 |
0.2 |
setosa |
4.4 |
2.9 |
1.4 |
0.2 |
setosa |
4.9 |
3.1 |
1.5 |
0.1 |
setosa |
5.4 |
3.7 |
1.5 |
0.2 |
setosa |
4.8 |
3.4 |
1.6 |
0.2 |
setosa |
4.8 |
3.0 |
1.4 |
0.1 |
setosa |
4.3 |
3.0 |
1.1 |
0.1 |
setosa |
5.8 |
4.0 |
1.2 |
0.2 |
setosa |
5.7 |
4.4 |
1.5 |
0.4 |
setosa |
5.4 |
3.9 |
1.3 |
0.4 |
setosa |
5.1 |
3.5 |
1.4 |
0.3 |
setosa |
5.7 |
3.8 |
1.7 |
0.3 |
setosa |
5.1 |
3.8 |
1.5 |
0.3 |
setosa |
5.4 |
3.4 |
1.7 |
0.2 |
setosa |
5.1 |
3.7 |
1.5 |
0.4 |
setosa |
4.6 |
3.6 |
1.0 |
0.2 |
setosa |
5.1 |
3.3 |
1.7 |
0.5 |
setosa |
4.8 |
3.4 |
1.9 |
0.2 |
setosa |
5.0 |
3.0 |
1.6 |
0.2 |
setosa |
5.0 |
3.4 |
1.6 |
0.4 |
setosa |
5.2 |
3.5 |
1.5 |
0.2 |
setosa |
5.2 |
3.4 |
1.4 |
0.2 |
setosa |
4.7 |
3.2 |
1.6 |
0.2 |
setosa |
4.8 |
3.1 |
1.6 |
0.2 |
setosa |
5.4 |
3.4 |
1.5 |
0.4 |
setosa |
5.2 |
4.1 |
1.5 |
0.1 |
setosa |
5.5 |
4.2 |
1.4 |
0.2 |
setosa |
4.9 |
3.1 |
1.5 |
0.2 |
setosa |
5.0 |
3.2 |
1.2 |
0.2 |
setosa |
5.5 |
3.5 |
1.3 |
0.2 |
setosa |
4.9 |
3.6 |
1.4 |
0.1 |
setosa |
4.4 |
3.0 |
1.3 |
0.2 |
setosa |
5.1 |
3.4 |
1.5 |
0.2 |
setosa |
5.0 |
3.5 |
1.3 |
0.3 |
setosa |
4.5 |
2.3 |
1.3 |
0.3 |
setosa |
4.4 |
3.2 |
1.3 |
0.2 |
setosa |
5.0 |
3.5 |
1.6 |
0.6 |
setosa |
5.1 |
3.8 |
1.9 |
0.4 |
setosa |
4.8 |
3.0 |
1.4 |
0.3 |
setosa |
5.1 |
3.8 |
1.6 |
0.2 |
setosa |
4.6 |
3.2 |
1.4 |
0.2 |
setosa |
5.3 |
3.7 |
1.5 |
0.2 |
setosa |
5.0 |
3.3 |
1.4 |
0.2 |
setosa |
7.0 |
3.2 |
4.7 |
1.4 |
versicolor |
6.4 |
3.2 |
4.5 |
1.5 |
versicolor |
6.9 |
3.1 |
4.9 |
1.5 |
versicolor |
5.5 |
2.3 |
4.0 |
1.3 |
versicolor |
6.5 |
2.8 |
4.6 |
1.5 |
versicolor |
Pandoc supports several types of Markdown tables, such as simple tables, multiline tables, grid tables, and pipe tables. What knitr::kable()
generates is a simple table like this:
Table: A simple table in Markdown.
Sepal.Length Sepal.Width Petal.Length Petal.Width
------------- ------------ ------------- ------------
5.1 3.5 1.4 0.2
4.9 3.0 1.4 0.2
4.7 3.2 1.3 0.2
4.6 3.1 1.5 0.2
5.0 3.6 1.4 0.2
5.4 3.9 1.7 0.4
You can use any types of Markdown tables in your document. To be able to cross-reference a Markdown table, it must have a labeled caption of the form Table: (\#label) Caption here
, where label
must have the prefix tab:
, e.g., tab:simple-table
.
If you decide to use other R packages to generate tables, you have to make sure the label for the table environment appears in the beginning of the table caption in the form (\#label)
(again, label
must have the prefix tab:
). You have to be very careful about the portability of the table generating function: it should work for both HTML and LaTeX output automatically, so it must consider the output format internally (check knitr::opts_knit$get('rmarkdown.pandoc.to')
). When writing out an HTML table, the caption must be written in the <caption></caption>
tag. For simple tables, kable()
should suffice. If you have to create complicated tables (e.g., with certain cells spanning across multiple columns/rows), you will have to take the aforementioned issues into consideration.
Cross-references
We have explained how cross-references work for equations (Section D.2.1), theorems (Section D.2.2), figures (Section D.4), and tables (Section D.5). In fact, you can also reference sections using the same syntax \@ref(label)
, where label
is the section ID. By default, Pandoc will generate an ID for all section headers, e.g., a section # Hello World
will have an ID hello-world
. We recommend you to manually assign an ID to a section header to make sure you do not forget to update the reference label after you change the section header. To assign an ID to a section header, simply add {#id}
to the end of the section header. Further attributes of section headers can be set using standard Pandoc syntax.
When a referenced label cannot be found, you will see two question marks like ??, as well as a warning message in the R console when rendering the book.
You can also create text-based links using explicit or automatic section IDs or even the actual section header text.
- If you are happy with the section header as the link text, use it inside a single set of square brackets:
[Section header text]
: example “[A single document]” via [A single document]
- There are two ways to specify custom link text:
[link text][Section header text]
, e.g., “[non-English books][Internationalization]” via [non-English books][Internationalization]
[link text](#ID)
, e.g., “Table stuff” via [Table stuff](#tables)
The Pandoc documentation provides more details on automatic section IDs and implicit header references.
Cross-references still work even when we refer to an item that is not on the current page of the PDF or HTML output. For example, see Equation (D.1) and Figure D.4.
Custom blocks
You can generate custom blocks using the block
engine in knitr, i.e., the chunk option engine = 'block'
, or the more compact syntax ```{block}
. This engine should be used in conjunction with the chunk option type
, which takes a character string. When the block
engine is used, it generates a <div>
to wrap the chunk content if the output format is HTML, and a LaTeX environment if the output is LaTeX. The type
option specifies the class of the <div>
and the name of the LaTeX environment. For example, the HTML output of this chunk
{block, type='FOO'} Some text for this block.
will be this:
<div class="FOO">
Some text for this block.
</div>
and the LaTeX output will be this:
\begin{FOO}
Some text for this block.
\end{FOO}
It is up to the book author how to define the style of the block. You can define the style of the <div>
in CSS and include it in the output via the includes
option in the YAML metadata. Similarly, you may define the LaTeX environment via \newenvironment
and include the definition in the LaTeX output via the includes
option. For example, we may save the following style in a CSS file, say, style.css
:
div.FOO {
font-weight: bold;
color: red;
}
And the YAML metadata of the R Markdown document can be:
---
output:
bookdown::html_book:
includes:
in_header: style.css
---
We have defined a few types of blocks for this book to show notes, tips, and warnings, etc. Below are some examples:
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.
The knitr block
engine was designed to display simple content (typically a paragraph of plain text). You can use simple formatting syntax such as making certain words bold or italic, but more advanced syntax such as citations and cross-references will not work. However, there is an alternative engine named block2
that supports arbitrary Markdown syntax, e.g.,
```{block2, type='FOO'}
Some text for this block [@citation-key].
- a list item
- another item
More text.
```
The block2
engine should also be faster than the block
engine if you have a lot of custom blocks in the document, but its implementation was based on a hack, so we are not 100% sure if it is always going to work in the future. We have not seen problems with Pandoc v1.17.2 yet.
One more caveat for the block2
engine: if the last element in the block is not an ordinary paragraph, you must leave a blank line at the end, e.g.,
```{block2, type='FOO'}
Some text for this block [@citation-key].
- a list item
- another item
- end the list with a blank line
```
The theorem and proof environments in Section D.2.2 are actually implemented through the block2
engine.
For all custom blocks based on the block
or block2
engine, there is one chunk option echo
that you can use to show (echo = TRUE
) or hide (echo = FALSE
) the blocks.
Citations
Although Pandoc supports multiple ways of writing citations, we recommend you to use BibTeX databases because they work best with LaTeX/PDF output. Pandoc can process other types of bibliography databases with the utility pandoc-citeproc
(https://github.com/jgm/pandoc-citeproc), but it may not render certain bibliography items correctly (especially in case of multiple authors per item), and BibTeX can do a better job when the output format is LaTeX. With BibTeX databases, you will be able to define the bibliography style if it is required by a certain publisher or journal.
A BibTeX database is a plain-text file (with the conventional filename extension .bib
) that consists of bibliography entries like this:
@Manual{R-base,
title = {R: A Language and Environment for Statistical
Computing},
author = {{R Core Team}},
organization = {R Foundation for Statistical Computing},
address = {Vienna, Austria},
year = {2016},
url = {https://www.R-project.org/},
}
A bibliography entry starts with @type{
, where type
may be article
, book
, manual
, and so on. Then there is a citation key, like R-base
in the above example. To cite an entry, use @key
or [@key]
(the latter puts the citation in braces), e.g., @R-base
is rendered as @R-base, and [@R-base]
generates “[@R-base]”. If you are familiar with the natbib package in LaTeX, @key
is basically \citet{key}
, and [@key]
is equivalent to \citep{key}
.
There are a number of fields in a bibliography entry, such as title
, author
, and year
, etc. You may see https://en.wikipedia.org/wiki/BibTeX for possible types of entries and fields in BibTeX.
There is a helper function write_bib()
in knitr to generate BibTeX entries automatically for R packages. Note that it only generates one BibTeX entry for the package itself at the moment, whereas a package may contain multiple entries in the CITATION
file, and some entries are about the publications related to the package. These entries are ignored by write_bib()
.
# the second argument can be a .bib file
knitr::write_bib(c('knitr', 'stringr'), '', width = 60)
@Manual{R-knitr,
title = {knitr: A General-Purpose Package for Dynamic Report
Generation in R},
author = {Yihui Xie},
year = {2019},
note = {R package version 1.23},
url = {https://CRAN.R-project.org/package=knitr},
}
@Manual{R-stringr,
title = {stringr: Simple, Consistent Wrappers for Common
String Operations},
author = {Hadley Wickham},
year = {2019},
note = {R package version 1.4.0},
url = {https://CRAN.R-project.org/package=stringr},
}
Once you have one or multiple .bib
files, you may use the field bibliography
in the YAML metadata of your first R Markdown document (which is typically index.Rmd
), and you can also specify the bibliography style via biblio-style
(this only applies to PDF output), e.g.,
---
bibliography: ["one.bib", "another.bib", "yet-another.bib"]
biblio-style: "apalike"
link-citations: true
---
The field link-citations
can be used to add internal links from the citation text of the author-year style to the bibliography entry in the HTML output.
When the output format is LaTeX, citations will be automatically put in a chapter or section. For non-LaTeX output, you can add an empty chapter as the last chapter of your book. For example, if your last chapter is the Rmd file 06-references.Rmd
, its content can be an inline R expression:
`r if (knitr::is_html_output()) '# References {-}'`
Index
Currently the index is only supported for LaTeX/PDF output. To print an index after the book, you can use the LaTeX package makeidx in the preamble (see Section ??):
\usepackage{makeidx}
\makeindex
Then insert \printindex
at the end of your book through the YAML option includes -> after_body
. An index entry can be created via the \index{}
command in the book body, e.g., \index{GIT}
.
The function install_phantomjs()
works for Windows, OS X, and Linux. You may also choose to download and install PhantomJS by yourself, if you are familiar with modifying the system environment variable PATH
.
When knitr detects an HTML widget object in a code chunk, it either renders the widget normally when the current output format is HTML, or saves the widget as an HTML page and calls webshot to capture the screen of the HTML page when the output format is not HTML. Here is an example of a table created from the DT package [@R-DT]:
DT::datatable(iris)
If you are reading this book as web pages now, you should see an interactive table generated from the above code chunk, e.g., you may sort the columns and search in the table. If you are reading a non-HTML version of this book, you should see a screenshot of the table. The screenshot may look a little different with the actual widget rendered in the web browser, due to the difference between a real web browser and PhantomJS’s virtual browser.
There are a number of knitr chunk options related to screen-capturing. First, if you are not satisfied with the quality of the automatic screenshots, or want a screenshot of the widget of a particular state (e.g., after you click and sort a certain column of a table), you may capture the screen manually, and provide your own screenshot via the chunk option screenshot.alt
(alternative screenshots). This option takes the paths of images. If you have multiple widgets in a chunk, you can provide a vector of image paths. When this option is present, knitr will no longer call webshot to take automatic screenshots.
Second, sometimes you may want to force knitr to use static screenshots instead of rendering the actual widgets even on HTML pages. In this case, you can set the chunk option screenshot.force = TRUE
, and widgets will always be rendered as static images. Note that you can still choose to use automatic or custom screenshots.
Third, webshot has some options to control the automatic screenshots, and you may specify these options via the chunk option screenshot.opts
, which takes a list like list(delay = 2, cliprect = 'viewport')
. See the help page ?webshot::webshot
for the full list of possible options, and the package vignette vignette('intro', package = 'webshot')
illustrates the effect of these options. Here the delay
option can be important for widgets that take long time to render: delay
specifies the number of seconds to wait before PhantomJS takes the screenshot. If you see an incomplete screenshot, you may want to specify a longer delay (the default is 0.2 seconds).
Fourth, if you feel it is slow to capture the screenshots, or do not want to do it every time the code chunk is executed, you may use the chunk option cache = TRUE
to cache the chunk. Caching works for both HTML and non-HTML output formats.
Screenshots behave like normal R plots in the sense that many chunk options related to figures also apply to screenshots, including fig.width
, fig.height
, out.width
, fig.cap
, and so on. So you can specify the size of screenshots in the output document, and assign figure captions to them as well. The image format of the automatic screenshots can be specified via the chunk option dev
, and possible values are pdf
, png
, and jpeg
. The default for PDF output is pdf
, and it is png
for other types of output. Note that pdf
may not work as faithfully as png
: sometimes there are certain elements on an HTML page that fail to render to the PDF screenshot, so you may want to use dev = 'png'
even for PDF output. It depends on specific cases of HTML widgets, and you can try both pdf
and png
(or jpeg
) before deciding which format is more desirable.