rr-markdownflextable

How can I output multiple flextable objects in R Markdown


Does anyone know if it is possible to loop through a list that varies in length of arguments to input into a custom function that outputs a flextable object in a word document using R Markdown? This is supposed to occur based on params in an R Markdown file.

I have tried using lapply but I keep getting the html or str() outputting into my word file. I have a temporary solution of making an R Markdown chunk for every item I may output and including a logical test for if we should output that table or not.

---
output:
  officedown::rdocx_document:
params:
  universe_report: TRUE
  homeworld_name: "Tatooine"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
```{r}
library(tidyverse)
library(flextable)

df = starwars %>% 
  mutate(hair_color_none = if_else(hair_color == "none", TRUE, FALSE, missing = FALSE))

custom_flextable = function(homeworld = "Tatooine", hair_color_none = TRUE){
  
  df = df %>% filter(!!homeworld == homeworld)
  
  if(hair_color_none){
    data = data.frame(
      df$hair_color,    
      df$eye_color    
    )
  }else{
    data = data.frame(
      df$height,    
      df$mass    
    )
  }
  
  data %>% 
    flextable() %>% 
    return()
}
```

Heading for Homeworld r params$homeworld_name
No Hair Color

```{r}
  if(params$universe_report==FALSE) custom_flextable(homeworld = params$homeworld_name,hair_color_none = FALSE)
```

Hair Color

```{r}
  if(params$universe_report==FALSE) custom_flextable(homeworld = params$homeworld_name,hair_color_none = TRUE)
```

Heading for Universe Report
No Hair Color

```{r}
if(params$universe_report) custom_flextable(homeworld = "Tatooine",hair_color_none = TRUE)
```
```{r}
if(params$universe_report) custom_flextable(homeworld = "Naboo",hair_color_none = TRUE)
```
```{r}
if(params$universe_report) custom_flextable(homeworld = "etc...",hair_color_none = TRUE)
```

Hair Color

```{r}
if(params$universe_report) custom_flextable(homeworld = "Tatooine",hair_color_none = FALSE)
```
```{r}
if(params$universe_report) custom_flextable(homeworld = "Naboo",hair_color_none = FALSE)
```
```{r}
if(params$universe_report) custom_flextable(homeworld = "etc...",hair_color_none = FALSE)
```

I already tried solution Looping Flextables in R Markdown documents with Word output which isn't working.


Solution

  • The following example should help, it uses flextable_to_rmd() and knitr chunk option results='asis':

    ---
    output:
      officedown::rdocx_document:
    params:
      universe_report: TRUE
      homeworld_name: "Tatooine"
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = FALSE)
    ```
    
    
    
    ```{r}
    library(tidyverse)
    library(officer)
    library(flextable)
    loop_details <- starwars |> 
      select(sex) |> 
      distinct() |> 
      drop_na()
    ```
    
    ```{r loop, results='asis'}
    for(i in seq_len(nrow(loop_details))) {
      cat("\n\n## ", loop_details[[i, "sex"]], "\n\n")
      starwars |> 
        filter(sex %in% loop_details[[i, "sex"]]) |> 
        summarise(mean_height = mean(height, na.rm = TRUE),
                  mean_mass = mean(mass, na.rm = TRUE),
                  .by = c(homeworld, species)) |>
      flextable() |> flextable_to_rmd()# use only in for loop
    }
    ```