RStudio rmarkdown: 在一个单独的 PDF 中同时使用纵向和横向布局

我想知道如何使用 rmarkdown来生成一个 PDF 文件,在同一文件中有纵向和横向布局。如果有一个纯 rmarkdown选项,这将是甚至比使用乳胶更好。

这里有一个可重复的小例子。首先,在 RStudio 中渲染这个 .Rmd(按 编织 PDF按钮)会生成一个 pdf,其中包含所有横向布局的页面:

---
title: "All pages landscape"
output: pdf_document
classoption: landscape
---


```{r}
summary(cars)
```


\newpage
```{r}
summary(cars)
```

然后尝试创建一个混合了纵向和横向布局的文档。YAML中的基本设置是根据“包含”部分 这里完成的。in_header文件“ header.tex”只包含 \usepackage{lscape},这是一个建议用于 knitr景观布局 这里的包。.tex文件与 .Rmd文件位于同一目录中。

---
title: "Mixing portrait and landscape"
output:
pdf_document:
includes:
in_header: header.tex
---


Portrait:
```{r}
summary(cars)
```


\newpage
\begin{landscape}
Landscape:
```{r}
summary(cars)
```
\end{landscape}


\newpage
More portrait:
```{r}
summary(cars)
```

但是,这段代码会导致一个错误:

# ! You can't use `macro parameter character #' in horizontal mode.
# l.116 #


# pandoc.exe: Error producing PDF from TeX source
# Error: pandoc document conversion failed with error 43

非常感谢你的帮助。

66886 次浏览

So, pandoc does not parse the content of latex environments, but you can fool it by redefining the commands in your header.tex file:

\usepackage{lscape}
\newcommand{\blandscape}{\begin{landscape}}
\newcommand{\elandscape}{\end{landscape}}

Thus, here \begin{landscape} is redefined to \blandscape, and \end{landscape} to \elandscape. Using those newly defined command in the .Rmd file seems to work:

---
title: "Mixing portrait and landscape"
output:
pdf_document:
includes:
in_header: header.tex
---


Portrait
```{r}
summary(cars)
```


\newpage
\blandscape
Landscape
```{r}
summary(cars)
```
\elandscape


\newpage
More portrait
```{r}
summary(cars)
```

As baptiste mentioned, if you enclose R commands within a LaTeX environment, pandoc will not parse them and will place them as they are into the generated LaTeX: this is what causes the error. Beyond baptiste's nice and simple fix, you could use the xtable R package, which offers the possibility of creating sexier-looking LaTeX tables from R output. For the following example to work, you need to add \usepackage{rotating} in the header.tex file:

---
title: "Mixing portrait and landscape"
output:
pdf_document:
keep_tex: true
includes:
in_header: header.tex
---
```{r, echo=FALSE}
library(xtable)
```


Portrait
```{r, results='asis', echo=FALSE}
print(xtable(summary(cars), caption="Landscape table"), comment=FALSE)
```


Landscape:
```{r, results='asis', echo=FALSE}
print(xtable(summary(cars), caption="Landscape table"),
floating.environment="sidewaystable", comment=FALSE)
```

The second table will be printed within the sidewaystable environment, rather than the usual table: therefore it will be printed in landscape mode, in a separate page. Note that tables and figures which are placed in landscape mode by the lscape package or in the sideways environment will always be placed in a separate page, see page 91 of this very important document:

http://www.tex.ac.uk/tex-archive/info/epslatex/english/epslatex.pdf

Since I find this a bit annoying, I managed to find a way to keep both portrait and landscape tables within the same page (wasting my whole afternoon in the process):

---
title: "Mixing portrait and landscape"
output:
pdf_document:
keep_tex: true
includes:
in_header: header.tex
---
```{r, echo=FALSE}
library(xtable)
```


Portrait:
```{r, results='asis', echo=FALSE}
print(xtable(summary(cars), caption="Portrait table."), comment=FALSE)
```


Landscape:
```{r, results='asis', echo=FALSE}
cat(paste0(
"\\begin{table}[ht]\\centering\\rotatebox{90}{",
paste0(capture.output(
print(xtable(summary(cars)), floating=FALSE, comment=FALSE)),
collapse="\n"),
"}\\caption{Landscape table.}\\end{table}"))
```

For the landscape table, I used the \rotatebox suggestion provided here:

http://en.wikibooks.org/wiki/LaTeX/Rotations

For this to work, I have to only generate the tabular part of the table with the print(xtable(... part, then I have to capture the output and "manually" surround it with the table and rotatebox commands, converting everything into a string R output so that pandoc does not see them as LaTeX environments. For a pure rmarkdown solution... good luck!

For the most common cases.

There are 3 conditions.

  1. Everything in portrait mode.
  2. Everything in landscape mode.
  3. Mixture of portrait and landscape modes.

Let’s narrow down to each conditions.

  1. The first one, say we have a markdown document start with the code below. And this is the default setting in Rstudio when you create an rmd file. When you knit it. It will automatically assume it’s a portrait mode without doubt.

    title: "Landscape and Portrait"
    author: "Jung-Han Wang"
    date: "Thursday, March 19, 2015"
    output: pdf_document
    
  2. When you want to knit the PDF file to landscape mode, the only thing you need to add is classoption: landscape

        title: "Landscape and Portrait"
    author: "Jung-Han Wang"
    date: "Thursday, March 19, 2015"
    output: pdf_document
    classoption: landscape
    
  3. If you want mixture of both, you will need to add .tex file in YAML. By referencing the link I mentioned above. You can download the .tex code here. http://goo.gl/cptOqg Or just simply copy the code and save it as header.tex Then, to make life easier, put this .tex file along with the rmd file to be knitted. Make sure you did these two things: Copy the tex file and move it along with the rmd file. Change the beginning of rmd to be:

     title: "Landscape and Portrait"
    author: "Jung-Han Wang"
    date: "Thursday, March 19, 2015"
    output:
    pdf_document:
    includes:
    in_header: header.tex
    

This is the summary after I played with this issue and mostly benefited from baptiste's answer.

I included some snapshots and examples in my blogger my blogger.

Hope this helps. Good luck.

Building upon previous solutions, the following solution does not require an auxiliary header.tex file. All contents are contained in the .Rmd file. The LaTeX commands are instead defined in a header-includes block in the YAML header. More info can be found here.

Also, I noticed that using the lscape LaTeX package rotates the contents of a page, but not the PDF page itself. This is resolved using the pdflscape package.

---
title: "Mixing portrait and landscape WITHOUT a header.tex file"
header-includes:
- \usepackage{pdflscape}
- \newcommand{\blandscape}{\begin{landscape}}
- \newcommand{\elandscape}{\end{landscape}}
output: pdf_document
---


Portrait
```{r}
summary(cars)
```


\newpage
\blandscape
Landscape
```{r}
summary(cars)
```
\elandscape


\newpage
More portrait
```{r}
summary(cars)
```