Rstudio rmarkdown: zarówno układ pionowy, jak i poziomy w jednym pliku PDF

86

Zastanawiam się, jak rmarkdownwygenerować plik PDF, który ma układ pionowy i poziomy w tym samym dokumencie. Jeśli istnieje czysta rmarkdownopcja, byłaby jeszcze lepsza niż użycie lateksu.

Oto mały, odtwarzalny przykład. Po pierwsze, renderowanie tego .Rmdw RStudio (naciśnij przycisk Knit PDF ) spowoduje powstanie pliku PDF ze wszystkimi stronami w układzie poziomym:

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

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

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

Następnie próba stworzenia dokumentu łączącego układ pionowy i poziomy. Podstawowa konfiguracja w programie YAMLjest wykonywana zgodnie z sekcją „Zawiera” tutaj . in_headerPlik „header.tex” zawiera tylko \usepackage{lscape}, pakiet sugerowanego przez knitrukładzie poziomym tutaj . .texPlik znajduje się w tym samym katalogu co .Rmdplik.

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

Jednak ten kod powoduje błąd:

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

Każda pomoc jest bardzo ceniona.

user3712688
źródło

Odpowiedzi:

81

Tak więc, pandoc nie analizuje zawartości środowisk latexowych, ale można to oszukać, ponownie definiując polecenia w header.texpliku:

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

Dlatego tutaj \begin{landscape}jest przedefiniowany do \blandscapei\end{landscape} do \elandscape. .RmdWydaje się, że używanie tych nowo zdefiniowanych poleceń w pliku działa:

---
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)
```
baptiste
źródło
Dziękuję za twoje badania i odpowiedź (+1). Opcja „nie analizuje zawartości środowisk lateksowych” nie jest do końca jasna w sekcji Zawiera . Ale zakładam, że moja latexignorancja jest również winna.
Henrik,
4
to złożony łańcuch narzędzi, z trzema / czterema różnymi graczami (knitr-rmarkdown / pandoc-latex) i stwierdzam, że poza udokumentowanymi rzeczami dość trudno jest ustalić, gdzie coś się psuje. Wydaje się, że najlepszym sposobem jest uruchamianie ich niezależnie: najpierw wykonaj dzianinę, spójrz na wynikową .md(dobrze, tutaj), a następnie konwersję md-> tex (tam poszła źle). Komunikat o błędzie nie był pomocny, ponieważ jest to już następny krok (lateks).
baptiste
Dzięki temu rozwiązaniu, w pliku PDF, zamiast strukturalnego nagłówka utworzonego przez „#Introduction”, # pojawia się jako symbol
JMarcelino
3
Chyba głupie pytanie z lateksu: gdzie jest (lub powinien) znajdować się plik header.tex, żeby go czytać? Często używam RMarkdown, ale jestem stosunkowo nowy i nie rozumiem jeszcze wszystkich powiązanych pakietów i tego, jak one ze sobą współpracują.
Mike Williamson
plik header.tex powinien znajdować się w tym samym katalogu
baptiste
50

Opierając się na poprzednich rozwiązaniach, poniższe rozwiązanie nie wymaga header.texpliku pomocniczego . Cała zawartość jest zawarta w .Rmdpliku. Zamiast tego polecenia LaTeX są zdefiniowane w header-includesbloku w nagłówku YAML. Więcej informacji można znaleźć tutaj .

Zauważyłem również, że użycie lscapepakietu LaTeX powoduje obrócenie zawartości strony, ale nie samej strony PDF. Można to rozwiązać za pomocą pdflscapepakietu.

---
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)
```
Megatron
źródło
1
W moim systemie to rozwiązanie nie działa. Używam wersji R-3.4.4, rmarkdown_1.9, knitr_1.20 na Mac OS_10.13.4. Zastanawiasz się, jaki może być problem?
Geochem B
@GeochemB Czy wymagane pakiety LaTeX są zainstalowane poprawnie? Niedawno odniosłem sukces z TinyTeX i polecam go.
Megatron
Nie zgłosili błędu, kiedy je zainstalowałem, ale sprawdzę i zgłoszę. Dzięki za ostrzeżenia, nie pomyślałem o tym i jestem nowy w wyprowadzaniu do formatu PDF / Latex.
Geochem B
@Megatron Przeszedłem przez narzędzie Tex Live i zainstalowałem i zaktualizowałem pakiet Oberdiek. Więc wymagania są, ale nadal nie ma kości. Nawet jeśli skopiuję / wkleję powyższy kod, nie ma zmiany orientacji.
Geochem B
1
@GeochemB Mam ten sam problem używając tego kodu. Próbowałem przeglądać dokument w SumatraPDF v3.1.1 oraz Adobe Acrobat DC i Pro. Z dokumentacji Oberdeik jest zawarty w MikTex. Zgodnie z moim zrozumieniem, jeśli mam zainstalowany MikTex, pdflscape powinien być dobry. Ciekawe, czy ktoś znalazł rozwiązanie.
Patrick
22

W najczęstszych przypadkach.

Istnieją 3 warunki.

  1. Wszystko w trybie portretowym.
  2. Wszystko w trybie poziomym.
  3. Połączenie trybów portretu i krajobrazu.

Zawęźmy do wszystkich warunków.

  1. Pierwsza, powiedzmy, że mamy dokument przeceny, zaczyna się od poniższego kodu. I to jest domyślne ustawienie w Rstudio podczas tworzenia pliku rmd. Kiedy to robisz na drutach. Bez wątpienia automatycznie przyjmie, że jest to tryb portretowy.

    title: "Landscape and Portrait"
        author: "Jung-Han Wang"
        date: "Thursday, March 19, 2015"
        output: pdf_document
    
  2. Jeśli chcesz połączyć plik PDF w tryb poziomy, jedyną rzeczą, którą musisz dodać, jest opcja class: pozioma

        title: "Landscape and Portrait"
        author: "Jung-Han Wang"
        date: "Thursday, March 19, 2015"
        output: pdf_document
        classoption: landscape
    
  3. Jeśli chcesz połączyć oba, będziesz musiał dodać plik .tex w YAML. Odwołując się do linku, o którym wspomniałem powyżej. Możesz pobrać kod .tex tutaj. http://goo.gl/cptOqg Lub po prostu skopiuj kod i zapisz go jako header.tex Następnie, dla ułatwienia życia, umieść ten plik .tex razem z plikiem rmd, który ma być łączony. Upewnij się, że wykonałeś te dwie rzeczy: Skopiuj plik tex i przenieś go razem z plikiem rmd. Zmień początek rmd na:

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

To jest podsumowanie po tym, jak bawiłem się tym problemem i najbardziej skorzystałem z odpowiedzi baptysty.

Dodałem kilka migawek i przykładów w moim blogerze, moim blogerze .

Mam nadzieję że to pomoże. Powodzenia.

Jung-Han Wang
źródło
2
Twoje podejście działa. Aby ułatwić zrozumienie, myślę, że problem z pandocem polega na tym, że robi się dziwnie, gdy używasz środowisk zamiast makr. Dlatego, jak zasugerowałeś, umieściłem w nagłówku (pakiet pdflandscape) \ newcommand {\ blcapes} {\ begin {krajobraz}} i \ newcommand {\ elcapes} {\ end {krajobraz}} i działało idealnie. Dzięki!
gvegayon
1
Wykonałem powyższe kroki (patrząc na bloga pomogło) i zadziałało świetnie. Dzięki!
Scott Worland
4

Jak wspomniał baptiste, jeśli umieścisz polecenia R w środowisku LaTeX, pandoc nie przeanalizuje ich i umieści je tak, jak są w wygenerowanym LaTeX: to jest przyczyną błędu. Poza ładną i prostą poprawką baptiste'a, możesz użyć xtablepakietu R, który oferuje możliwość tworzenia bardziej seksownych tabel LaTeX z wyjścia R. Aby poniższy przykład zadziałał, musisz dodać \usepackage{rotating}w header.texpliku:

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

Druga tabela zostanie wydrukowana w sidewaystableśrodowisku, a nie normalnie table: dlatego zostanie wydrukowana w trybie poziomym, na oddzielnej stronie. Zwróć uwagę, że tabele i rysunki, które są umieszczone w trybie poziomym przez lscapeopakowanie lub w sidewaysotoczeniu, zawsze będą umieszczane na oddzielnej stronie, patrz strona 91 tego bardzo ważnego dokumentu:

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

Ponieważ uważam to za trochę irytujące, udało mi się znaleźć sposób na utrzymanie tabel portretowych i poziomych na tej samej stronie (marnując przy tym całe popołudnie):

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

W przypadku tabeli poziomej skorzystałem z \rotateboxsugestii podanej tutaj:

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

Aby to zadziałało, muszę tylko wygenerować tabularczęść tabeli z print(xtable(...częścią, a następnie muszę przechwycić wyjście i "ręcznie" otoczyć je poleceniami tablei rotatebox, konwertując wszystko na wyjście ciągu R, aby pandoc nie widział je jako środowiska LaTeX. Dla czystego rozwiązania rmarkdown ... powodzenia!

renato vitolo
źródło
To jedyny na tej stronie, który działał dla mnie. Dzięki, Renato!
Stuart,