rr-markdownpandocpander

Italicising the headings of a dataframe in rmarkdown


I would like to apply some latex-style formatting to column headings in a pander table in rmarkdown, knitting to pdf.

Notice in the toy document below the latex commands that work for the elements of the dataframe do not work for the headings. Specifically I would like (1) to be able to italicise some headings, (2) to be able to have headings with spaces between the letters (at the moment R automatically adds a .). However I am generally interested in how to get the headings in a dataframe to accept the same latex commands as the elements of the dataframe.

 ---
title: "Chapter 12: Adding to the Discrete Time Hazard Model"
output:
  pdf_document: default
  html_document: null
  word_document: null
toc: yes
linestretch: 1.3
classoption: fleqn
header-includes: 
 - \setlength{\mathindent}{0pt}
 - \setlength\parindent{0pt}
 - \usepackage{amssymb}
---

```{r global_options, include=FALSE, echo = FALSE}
#this sets global knit options (i.e. options for the entire document. The following supresses any warnings from being include in the output and sets plot parameters. Note that setting dev to pdf allows us to set size of graphs easily
rm(list = ls())

knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/', 
                      echo=FALSE, warning=FALSE, message=FALSE, dev = 'pdf')
```

``` {r table p 446}
abC <- 0.3600344
bC <- 0.2455304 
intC <- 0.4787285


dfTrans <- data.frame("Prototype" = c("$\\textit{Left/not Blue}$", "Left/Blue", "Right/not Blue", "Right/Blue"),
                      "$LEFT$" = c(0,1,0,1),
                      "$\\textit{BLUE}$" = c(0,0,1,1),
                      `Combined Parameter Estimates` = c(paste("0 x ", round(abC,4), "+ 0 x", round(bC,4), "+ 0 x", round(intC, 4), sep = " "),  8, 9, 0))


library(pander)
panderOptions('table.split.table', 300) # this forces the table to the width of the page. 
pander(dfTrans, justify = "left")
```

Solution

  • I'm not sure how to do this with pander, but here is a method using the kable function from knitr and kableExtra functions for detailed table formatting. I haven't changed the yaml markup, but the updated code chunks are pasted in below, followed by the output.

    ```{r global_options, include=FALSE, echo = FALSE}
    #this sets global knit options (i.e. options for the entire document. The following supresses any warnings from being include in the output and sets plot parameters. Note that setting dev to pdf allows us to set size of graphs easily
    knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/', 
                          echo=FALSE, warning=FALSE, message=FALSE, dev = 'pdf')
    
    # rm(list = ls()) This is unnecessary. knitr runs the rmarkdown document in a clean session.
    
    library(knitr)
    library(kableExtra)
    options(knitr.table.format = "latex")  # latex output (instead of default html)
    library(tidyverse) # For dplyr pipe (%>%) and mutate
    ```
    
    ```{r table p 446}
    abC <- 0.3600344
    bC <- 0.2455304 
    intC <- 0.4787285
    
    # I've removed the latex formatting from the data frame code
    dfTrans <- data.frame(Prototype = c("Italic_Left/not Blue", "Left/Blue", "Right/not Blue", "Right/Blue"),
                          LEFT = c(0,1,0,1),
                          BLUE = c(0,0,1,1),
                          `Combined Parameter Estimates` = c(paste("0 x ", round(abC,4), "+ 0 x", round(bC,4), "+ 0 x", round(intC, 4), sep = " "),  8, 9, 0))
    
    # Remove periods in column names
    names(dfTrans) = gsub("\\.", " ", names(dfTrans))
    # Two other options: 
    # 1. Use the data_frame function from tidyverse, rather than the base data.frame function. 
    #    data_frame doesn't add periods, so you won't need to fix the column names afterwards.
    # 2. Set check.names=FALSE in data.frame
    
    # Use kableExtra cell_spec function to format on a cell-by-cell basis
    dfTrans = dfTrans %>% 
      mutate(Prototype = cell_spec(Prototype, color=c("black","blue"),
                                   align=rep(c("l","r"), each=2)))
    
    # Format each of the column names using kableExtra text_spec
    names(dfTrans)[1] = text_spec(names(dfTrans)[1], italic=TRUE)
    names(dfTrans)[2] = text_spec(names(dfTrans)[2], align="l")
    names(dfTrans)[3] = text_spec(names(dfTrans)[3], align="r", italic=TRUE, color="blue")
    names(dfTrans)[4] = text_spec(names(dfTrans)[4], align="r")
    
    # Output the table
    kable(dfTrans, booktabs=TRUE, escape=FALSE) 
    ```
    

    enter image description here

    One thing I'm not sure how to do yet is to format just the first value of dfTrans$Prototype as italic. cell_spec seems to use only the first value of an italic logical vector, so the following italicizes the whole column:

    dfTrans = dfTrans %>% 
      mutate(Prototype = cell_spec(Prototype, color=c("black","blue"),
                                   align=rep(c("l","r"), each=2),
                                   italic=c(TRUE, rep(FALSE, n()-1))))