Rstudio rmarkdown: both portrait and landscape layout in a single PDF
Asked Answered
G

6

114

I wonder how to use rmarkdown to generate a pdf which has both portrait and landscape layout in the same document. If there is a pure rmarkdown option that would be even better than using latex.

Here's a small, reproducible example. First, rendering this .Rmd in RStudio (press Knit PDF button) results in a pdf with all pages in landscape layout:

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

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

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

Then an attempt to create a document which mixes portrait and landscape layout. The basic setup in the YAML is done according to the 'Includes' section here. The in_header file 'header.tex' only contains \usepackage{lscape}, a package suggested for knitr landscape layout here. The .tex file is in the same directory as the .Rmd file.

---
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)
```

However, this code results in an error:

# ! 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

Any help is much appreciated.

Gaslit answered 15/9, 2014 at 13:58 Comment(0)
J
111

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)
```
Jeroboam answered 6/12, 2014 at 17:16 Comment(8)
Thanks for your research and answer (+1). The 'does not parse the content of latex environments' is not entirely clear from the Includes section. But I assume my latex ignorance is to blame as well.Upholstery
it's a complex toolchain, with three/four different players (knitr-rmarkdown/pandoc-latex) and I find that outside the documented stuff, it's quite hard to figure out where things break. The best way seems to run them independently: first knit, look at the resulting .md (fine, here), then the md->tex conversion (that's where it went wrong). The error message was not helpful because it's already the next step (latex).Jeroboam
With this solution, in the pdf, instead of the structured header created by "#Introduction", the # appears as a symbolColeen
I guess dumb latex question: where does (or should) the header.tex file live, so that it is read? I use RMarkdown heavily, but am relatively new, and haven't yet understood all the interlocking packages & how they are working together.Aynat
the header.tex file should be in the same directoryJeroboam
@Coleen I encountered the same problem with the "#" did you find a solution in the meantime?Schematic
It is unfortunate that pandoc has to be fooled into thinking it is not inside of a LaTeX environment for it to do its magic. (This means that in the future, when pandoc gets smarter, this trick might stop to work.) Ideally, there had been some way to tell pandoc to parse specific parts of latex environments (wherever desired) instead of having to rely on this workaround. But hey, better some way than no way.Psychophysiology
Using this method, the page number is on the left side, not the bottom of the page. Any ideas?Backplate
P
77

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)
```
Polycrates answered 30/1, 2017 at 21:10 Comment(10)
On my system, this solution is not working. I am running R-3.4.4, rmarkdown_1.9, knitr_1.20 on a Mac OS_10.13.4. Wondering what may be the issue?Briscoe
@GeochemB Are the requisite LaTeX packages installed correctly? I've recently had success with TinyTeX and recommend it.Polycrates
They didn't throw an error when I installed them, but I'll double check and report. Thanks for the heads up, I hadn't thought of that and am new to outputting to a PDF/Latex.Briscoe
@Polycrates I went through the Tex Live utility and have the Oberdiek package installed and updated. So the requirements are there, but still no dice. Even when i copy/paste the code above there is no change to the orientation.Briscoe
@GeochemB What is the Oberdiek package for? Do you have the pdflscape package installed? What PDF viewer are you using?Polycrates
Oberdeik is a package bundle which includes pdflscape (ctan.org/pkg/oberdiek), and I am using Acrobat.Briscoe
@GeochemB I got the same problem using this code. I tried viewing the document in SumatraPDF v3.1.1 and Adobe Acrobat DC and Pro. From the documentation Oberdeik is included in MikTex. As per my understanding if I have MikTex installed the pdflscape should be good. Curious if anyone got a solution.Suave
This didn't work for me at first (Windows 10, RStudio 1.3.1093, R 4.0.0), but after opening MikTeX console as Administrator and updating all LaTeX packages it works great.Theocrasy
This works great but the page numbers print sideways on the left hand side of the landscape pages. Is there an easy way to deal with this and still have page numbers?Imbroglio
I have the same question as @djhocking. Does anybody know the answer?Pincenez
R
26

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.

Rosabella answered 20/3, 2015 at 13:21 Comment(2)
Your approach works. To make it easier to understand, I think that the problem with pandoc is that it gets weird when you use environments instead of macros. That's why I included, as you suggested, \newcommand{\blandscape}{\begin{landscape}} and \newcommand{\elandscape}{\end{landscape}} in my header (the pdflandscape package), and it worked perfectly. Thanks!Sulfamerazine
The link to the code is deadIndelicacy
P
7

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!

Puckett answered 7/12, 2014 at 16:26 Comment(1)
This is the only one on this page that worked for me. Thanks, Renato!Ripen
J
1

If you just want a landscape table the easiest thing is to use kableExtra::landscape. See page 26: http://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf

Jehius answered 19/6, 2023 at 13:56 Comment(0)
S
0

Using a header.tex and adding the lines below, as suggested in other answers, works well for me.

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

However, as pointed out in some of the comments, this also rotates the page numbers, such that they position on the lefthand side of landscape pages. they're also facing the wrong way. If you're okay with simply ommitting page numbers, adding this LatEx line to your RMarkdown file works to resolve the issue.

\pagenumbering{gobble}

If, however, you want to keep page numbers and position them at the bottom of the page, you may find a solution with custom page numbers using the fancyhdr and lastpage LaTeX packages as suggested here.

Simulation answered 22/6, 2023 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.