R kable won't print in Markdown document

5.7k Views Asked by At

I have recently tried to use the kable package for tables, and while I'm quite satisfied of the results I'm getting in R scripts, I can't figure out how to use them in an R Markdown file.

Here is a short example of a table that does work in a R script, but won't when I try to reproduce it in a Markdown document.

data(mtcars)

mtcars

## @knitr install

check_and_install <- function( packname ) { # given package name, check installation, install if not found
  if ( packname %in% rownames(installed.packages()) == FALSE ) {
install.packages( packname, repos="http://cran.rstudio.com/"  )
  }
}

check_and_install("kableExtra")
check_and_install("dplyr")
check_and_install("qwraps2")
check_and_install("reprex")

library(kableExtra)
library(dplyr)
library(qwraps2)
library(reprex)

## Tableau

summary_test  <-
  list("Cylindres" =
     list("Huit" = ~ qwraps2::n_perc0(cyl == 8,show_symbol=TRUE),
          "Six" = ~ qwraps2::n_perc0(cyl == 6,show_symbol=TRUE),
          "Quatre"  = ~ qwraps2::n_perc0(cyl == 4,show_symbol=TRUE)),
   "Vitesses" =
     list("Cinq" = ~ qwraps2::n_perc0(gear == 5,show_symbol=TRUE),
          "Quatre" = ~ qwraps2::n_perc0(gear == 4,show_symbol=TRUE),
          "Trois" = ~ qwraps2::n_perc0(gear == 3,show_symbol=TRUE))
  )



tabtest2<-summary_table(dplyr::group_by(mtcars, am), summary_test)


kable_out <- kable(tabtest2, format = "html", caption = "",     col.names=c("Auto","Manuelle"), booktabs = T, full_width = F) %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>%
  kableExtra::group_rows("Cylindres", 1, 3) %>%
  kableExtra::group_rows("Vitesses", 4, 6) 

kable_out

Now as for the next step, I want to include this tab in a R-markdown document, ideally the output would be a word file. And this is where I'm having problems : I can't find a way to include it properly. Markdown completely messes up the formatting in the word output. Please note that there is no issue if I switch the output to HTML... unfortunately I have to provide a word document for now so that's not an option.

---
title: "Test2"
author: "MJ"
date: "14 mars 2019"
output: word_document
always_allow_html: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(cache = FALSE, include = FALSE)
library(knitr)
opts_chunk$set(echo = FALSE, cache=FALSE)
read_chunk('C:/Users/Mathieu/Desktop/indicateurs pps/Test SO.R')
```


```{r install, include=FALSE}
```

## Analyse comparative


```{r table1, include=T}
knitr::kable(tabtest2, format = "html", caption = "",     col.names=c("Auto","Manuelle"), booktabs = T, full_width = F) %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>%
  kableExtra::group_rows("Cylindres", 1, 3) %>%
  kableExtra::group_rows("Vitesses", 4, 6) 


kable_out
```

No issues at all when creating the document, everything seems to run smoothly...

I've been looking into it for a while and I just can't figure out what's wrong. Any leads someone ?

Thanks in advance

3

There are 3 best solutions below

1
Luke W. Johnston On

Thanks for the edits to make the example reproducible @Mathieu -

So a couple of things that I see are going on.

  1. You are outputting to Word but want to use html features. Word is not designed for having HTML features (like "hover", "striped", etc).
  2. You are trying to create a table from the table creator kable from another table creator summary_table. If you look at summary_table, it actually creates a LaTeX markup table. So there will be problems with converting from one table form to another.

I tested it out and there are three options:

Create a word document, but use qwarps2 to create the table

---
title: "Test2"
author: "MJ"
date: "14 mars 2019"
output: word_document
always_allow_html: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(cache = FALSE, include = FALSE)
library(knitr)
opts_chunk$set(echo = FALSE, cache=FALSE)
read_chunk("Test SO.R")
options(qwraps2_markup = "markdown") # this is new
```


```{r install, include=FALSE}
```

## Analyse comparative

```{r table1, include=TRUE, results='asis'}
tabtest2
```

Change nothing else and output a HTML document

---
title: "Test2"
author: "MJ"
date: "14 mars 2019"
output: html_document
always_allow_html: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(cache = FALSE, include = FALSE)
library(knitr)
opts_chunk$set(echo = FALSE, cache=FALSE)
read_chunk("Test SO.R")
```


```{r install, include=FALSE}
```

## Analyse comparative

```{r table1, include=TRUE, results='asis'}
knitr::kable(tabtest2, caption = "", format = "html", col.names=c("Auto","Manuelle"), booktabs = T,full_width = F) %>%
  kable_styling(bootstrap_options = c("striped", "hover")) %>%
  kableExtra::group_rows("Cylindres", 1, 3) %>%
  kableExtra::group_rows("Vitesses", 4, 6)
```

Try a different approach and don't use qwarps2

Why not just create the knitr table directly from the data? I.e. don't use qwraps2? To get similar functionality as qwarps2, try the carpenter package (disclaimer, I created it, but if it doesn't work there is a list of similar packages at the end of the README/first page). You can get the data into the way you want it for a table then at the end create a table from the wrangled data using knitr.

0
Peter On

Consider the following .Rmd file for an example use case and explanation.

---
title: "summary table"
output: rmarkdown::word_document
---

To get the summary table from the
`r  qwraps2::CRANpkg(qwraps2) `
package to render in a word document you need to *not* pass the return from
`r  qwraps2::backtick(summary_test) `
to
`r  paste0(qwraps2::backtick(knitr::kabel), ".") `

The reason is that
`r  qwraps2::backtick(summary_test) `
returns a character matrix and a
`r  qwraps2::backtick(print) `
method is reasponsible for generating either the markdown or LaTeX table.


```{r label = "install_cran", include = FALSE}
# remotes::install_cran is similar to your check_and_install function.
remotes::install_cran("kableExtra")
remotes::install_cran("dplyr")
remotes::install_cran("qwraps2")

```
```{r label = "namespaces"}
library(kableExtra)
library(qwraps2)
```


By default
`r  qwraps2::CRANpkg(qwraps2) `
will format results for LaTeX.  Set the default markup language to markdown
to change this behavior.

```{r }
options(qwraps2_markup = "markdown")
```

**EDIT:** as of version qwraps2 version 0.5.0 the use of the data pronoun
`.data` is no longer needed nor recommented.

```{r label = "define_summary_test"}
summary_test  <-
  list("Cylindres" =
     list("Huit"   = ~ qwraps2::n_perc0(cyl == 8, show_symbol = TRUE),
          "Six"    = ~ qwraps2::n_perc0(cyl == 6, show_symbol = TRUE),
          "Quatre" = ~ qwraps2::n_perc0(cyl == 4, show_symbol = TRUE)),
   "Vitesses" =
     list("Cinq"   = ~ qwraps2::n_perc0(gear == 5, show_symbol = TRUE),
          "Quatre" = ~ qwraps2::n_perc0(gear == 4, show_symbol = TRUE),
          "Trois"  = ~ qwraps2::n_perc0(gear == 3, show_symbol = TRUE))
  )
```


Finally, build the table and look at the structure of the object.


```{r label = 'tabtest2'}
tabtest2 <- summary_table(mtcars, summary_test, by = "am")
str(tabtest2)
```


Note that the object is a
`r  qwraps2::backtick(qwraps2_summary_table)  `
is a character matrix with attributes for the row, column, and row group
names.  Using the default print method in R we see a character matrix.

```{r }
print.default(tabtest2)
```


Using the print method for
`r  qwraps2::backtick(qwraps2_summary_table)  `
objects (done impliclity here) gives the markdown:

```{r results = "markup"}
tabtest2
```


To get the table to render nicely use the "asis" value for the results chunk
option:

```{r results = "asis"}
tabtest2
```

The output document looks like this:

enter image description here

0
JRB On

Before you load the kableExtra package, set:

options(kableExtra.auto_format = FALSE)

Your table should then show up in the rendered Word document. (Advice taken from here)