I have a solution that involves advanced knitr feature.
flextable
implements a knit_print.flextable
method as explained in knitr
vignette. You'll learn in this documentation about that render
chunk option that can allow to customise rendering in rmarkdown, and that default to knitr::knit_print
. In fact, it could be any function that return a character output to be printed.
If you look at flextable:::knit_print.flextable, you'll see that for html output, it uses htmltools_value
and for docx output (and pandoc > 2.0), it creates a character string with pandoc docx flags. This knit_print
method is applied only if the chunk returns a flextable object.
When you map
the regulartable()
function, the chunk return a list. So the knit_print
method is not correct. This is why if you apply knit_print
inside the map
you are close to the result. However the result of the chunk is still a list of element resulting for individual knit_print.flextable
call.
At the end, the result of the chunk is rendered to pandoc markdown so you need the correct render function in adequation with your result.
Thus, the solution : you could use a custom rendering function that knows how to deal with a list of regulartable()
output and create a character string corresponding to pandoc markdown - a concatenation of the knit_print.flextable
output.
For example, a function like that:
render_custom <- function(x, ...) {
# I use imap here because I create a title with name of the list
# I create a character string with the result of `knit_print.flextable`
imap_chr(x, ~ paste0("**Table: ",.y,"**\n", knit_print(.x))) %>%
# collapse all the results
paste(collapse = "\n") %>%
# knir must use this result `asis`
asis_output()
}
This function could then be use in the render
chunk option.
Full example that renders correctly on my computer:
---
title: "PURRR and tables for word"
output: word_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = TRUE,
warning = FALSE,
warnings = FALSE
)
```
```{r}
#libraries
library(knitr)
library(purrr)
library(flextable)
#the table
my_tab <- tibble::tribble(
~`Biogenic.Habitat/Species`, ~Limiting.Driver, ~`Max,.Min,.or.Mean`, ~Units, ~Value,
"Clams", "Flow Velocity", "Min", "m/s", 0.04,
"Mussel Bed", "Depth", "Max", "m", 10,
"Mussel Bed", "Flow Velocity", "Max", "m/s", 1.8,
"Mussel Bed", "Temperature", "Max", "C", 32,
"Oysters", "Flow Velocity", "Max", "m/s", 2.6,
"Oysters", "Flow Velocity", "Min", "m/s", 1.56)
#split it to a list
my_tab_split <- my_tab %>% split(.$`Biogenic.Habitat/Species`)
```
```{r, include = FALSE}
render_custom <- function(x, ...) {
# I use imap here because I create a title with name of the list
# I create a character string with the result of `knit_print.flextable`
imap_chr(x, ~ paste0("**Table: ",.y,"**\n", knit_print(.x))) %>%
# collapse all the results
paste(collapse = "\n") %>%
# knir must use this result `asis`
asis_output()
}
```
```{r, render=render_custom}
map(my_tab_split, ~regulartable(.x))
```
Let me know if it is clear and if it works. You can adapt render_custom
to your desire.