Search code examples
rmarkdownknitrxtable

Change heading and include bold font in xtable to .pdf from RMarkdown


I am a beginner with RMarkdown and LaTex, although enjoying creating reports in R! I have picked up some code to create the exact .pdf report I am after, although having difficulty with some aesthetics.

My data is confidential but here is a replica of layout/ exact number of plots and tables, using inbuilt R datasets.

---
title: <center> <h1>Call Centre Report</h1> </center>
mainfont: Arial
output:
  pdf_document:
    latex_engine: xelatex
sansfont: Arial
fig_crop: false
toc: true
classoption: landscape
fontsize: 14pt
geometry: margin=0.5in
header-includes:
- \usepackage{booktabs}
---
<style>
  .main-container {
    max-width: 1200px !important;
  }
</style>

```{r global_options, R.options=knitr::opts_chunk$set(warning=FALSE, message=FALSE)}
```
\newpage
# Iris 
```{r fig.width=18, fig.height=7, echo=FALSE, comment=" "}
library(ggplot2)
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
   geom_point() +
   theme_classic()
```
<br>
<br>
```{r, echo=FALSE, results='asis'}
library(knitr)
library(xtable)

t1 <- kable(subset(iris, Sepal.Length=="5.1", select = Petal.Length:Species),
            format = "latex", booktabs = TRUE, row.names = FALSE)
t2 <- kable(subset(chickwts, feed=="horsebean", select = weight:feed), 
            format = "latex", booktabs = TRUE, row.names = FALSE)
t3 <- kable(subset(mtcars, gear=="4", select = disp:wt), 
            format = "latex", booktabs = TRUE, row.names = FALSE, digits=2)

cat(c("\\begin{table}[!htb]
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t1,
    "\\end{minipage}%
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t2,
    "\\end{minipage}%
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t3,
    "\\end{minipage} 
\\end{table}"
)) 
```

I wish to tidy up the following, but am unsure how to do so:

  • Make the Iris heading on page 2 bold and centered, but keeping it as a heading in the table of contents.
    • Bold the headings in each of the three tables
    • Centre all the text in each table
    • Remove the big gap after 1.7, 0.5, setosa in Table 1 and consequently, the other tables in that row.

Any help or links to specific documentation would be greatly appreciated.

UPDATE

The answer provided below worked well except my data contains a percentage column, which RMarkdown and LaTeX does not seem to like. I have updated my code with some dummy data, that is very similar to my confidential data, in the hope this bug can be solved.

Thanks!

---
title: <center> <h1>Call Centre Report</h1> </center>
mainfont: Arial
output:
  pdf_document:
    latex_engine: xelatex
sansfont: Arial
fig_crop: false
toc: true
classoption: landscape
fontsize: 14pt
geometry: margin=0.5in
header-includes:
- \usepackage{booktabs}
---
<style>
  .main-container {
    max-width: 1200px !important;
  }
</style>

```{r global_options, R.options=knitr::opts_chunk$set(warning=FALSE, message=FALSE)}
```
\newpage

# Iris 

```{r fig.width=18, fig.height=7, echo=FALSE, comment=" "}
library(ggplot2)
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
   geom_point() +
   theme_classic()
```
<br>
<br>
```{r, echo=FALSE, results='asis'}
library(knitr)
library(xtable)

# Create some dummy data
Data <- data.frame(Fruit = sample(c("Apple", "Orange"), 10, replace = TRUE), 
                     Score = sample(1:10))
# Include percentage column
Data$Percentage <- (paste0(round(100 * Data$Score/100), "%"))

t1 <- kable({x <- subset(iris, Sepal.Length=="5.1", select = Petal.Length:Species);
             names(x) <- sprintf("\\textbf{%s}", names(x))
             x},
            format = "latex", booktabs = TRUE, row.names = FALSE,
            align = 'c', escape = FALSE)
t2 <- kable({x <- subset(chickwts, feed=="horsebean", select = weight:feed);
             names(x) <- sprintf("\\textbf{%s}", names(x))
             x},
            format = "latex", booktabs = TRUE, row.names = FALSE,
            align = 'c', escape = FALSE)
t3 <- kable({x <- subset(Data, Fruit=="Apple", select = Score:Percentage);
             names(x) <- sprintf("\\textbf{%s}", names(x))
             x},
            format = "latex", booktabs = TRUE, row.names = FALSE,
            align = 'c', escape = FALSE)

cat(c("\\begin{table}[!htb]
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t1,
    "\\end{minipage}%
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t2,
    "\\end{minipage}%
    \\begin{minipage}{.35\\linewidth}
      \\centering",
        t3,
    "\\end{minipage} 
\\end{table}"
)) 
```

Solution

  • For your table related issues, you can use the following to get your desired layout. The bold headings are obtained by wrapping the column names in \code{textbf}. If you wish to have table headings that can adapt to HTML output, you will need additional logic (or you'll need to use a different table generating package). With this, you need to set escape = TRUE in the kable call.

    Centering the content is as simple as using the align argument in the kable function.

    t1 <- kable({x <- subset(iris, Sepal.Length=="5.1", select = Petal.Length:Species);
                 names(x) <- sprintf("\\textbf{%s}", names(x))
                 x},
                format = "latex", booktabs = TRUE, row.names = FALSE,
                align = 'c', escape = FALSE)
    

    Your section heading would appear correctly if you put a line of white space both above and below # Iris.

    To get the section heading centered, you may want to search for tips on https://tex.stackexchange.com/

    pixiedust version

    for some reason I don't understand, I'm having to set the tabcolsep parameter in these tables. Inside the minipage environment, you will need to use float = FALSE. But this seems to give a good approximation of what you want without editing the data source.

    Where you are using percentages, you'll want to use sprinkle(halign = "center", sanitize = TRUE)

    ---
    title: <center> <h1>Call Centre Report</h1> </center>
    mainfont: Arial
    output: 
      pdf_document: 
        keep_tex: yes
    sansfont: Arial
    fig_crop: false
    toc: true
    classoption: landscape
    fontsize: 14pt
    geometry: margin=0.5in
    header-includes: 
    - \usepackage{amssymb} 
    - \usepackage{arydshln} 
    - \usepackage{caption} 
    - \usepackage{graphicx} 
    - \usepackage{hhline} 
    - \usepackage{longtable} 
    - \usepackage{multirow} 
    - \usepackage[dvipsnames,table]{xcolor} 
    - \usepackage{booktabs}
    ---
    <style>
      .main-container {
        max-width: 1200px !important;
      }
    </style>
    
    ```{r global_options, R.options=knitr::opts_chunk$set(warning=FALSE, message=FALSE)}
    ```
    \newpage
    
    # Iris 
    
    ```{r fig.width=18, fig.height=7, echo=FALSE, comment=" "}
    library(ggplot2)
    ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) +
       geom_point() +
       theme_classic()
    ```
    <br>
    <br>
    ```{r, echo=FALSE, results='asis'}
    library(knitr)
    library(xtable)
    library(pixiedust)
    
    t1 <- subset(iris, 
                 Sepal.Length == "5.1", 
                 select = Petal.Length:Species) %>%
      dust(float = FALSE) %>%
      sprinkle(tabcolsep = 10) %>%
      sprinkle(bold = TRUE,
               part = "head") %>%
      sprinkle(halign = "center") %>%
      medley_bw()
    
    t2 <- subset(chickwts, feed=="horsebean", select = weight:feed) %>%
      dust(float = FALSE) %>%
      sprinkle(tabcolsep = 10) %>%
      sprinkle(bold = TRUE,
               part = "head") %>%
      sprinkle(halign = "center") %>%
      medley_bw()
    
    t3 <- subset(mtcars, gear=="4", select = disp:wt) %>%
      dust(float = FALSE) %>%
      sprinkle(tabcolsep = 10) %>%
      sprinkle(bold = TRUE,
               part = "head") %>%
      sprinkle(halign = "center") %>%
      medley_bw()
    
    cat(c("\\begin{table}[!htb]
        \\begin{minipage}{.35\\linewidth}
          \\centering",
            print(t1, asis = FALSE),
        "\\end{minipage}%
        \\begin{minipage}{.35\\linewidth}
          \\centering",
            print(t2, asis = FALSE),
        "\\end{minipage}%
        \\begin{minipage}{.35\\linewidth}
          \\centering",
            print(t3, asis = FALSE),
        "\\end{minipage} 
    \\end{table}"
    )) 
    ```