15

I have many tables to create and am trying to create them in a loop. I'm using flextable with rmarkdown inside rstudio. Using print(theFlextable) command in a loop produces a list of text rather than the table. This happens for docx and html output types. If I don't use a loop flextable renders correctly. Here is a demo:

---
title: "Demo"
output: word_document
---

```{r setup, include=FALSE}
library(flextable)
```
## This Works
```{r iris, echo=F, message=F, error=F, results='asis'}
ft<-flextable(iris[1:10,])
ft
```
## This produces no output
```{r echo=F, message=F, error=F, results='asis'}
doThese<-c("setosa","virginica")
for (i in doThese){
  tbl<-subset(iris, Species==i)
  ft<-flextable(tbl[1:10,])
  ft
}
```
## This produces incorrect output
```{r echo=F, message=F, error=F, results='asis'}
doThese<-c("setosa","virginica")
for (i in doThese){
  tbl<-subset(iris, Species==i)
  ft<-flextable(tbl[1:10,])
  print(ft)
  cat("\n\n")
}
``` 

This is the output in word of the last block above:

type: flextable object. col_keys: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species header has 1 row(s) body has 10 row(s) original dataset sample: Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa

type: flextable object. col_keys: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species header has 1 row(s) body has 10 row(s) original dataset sample: Sepal.Length Sepal.Width Petal.Length Petal.Width Species 101 6.3 3.3 6.0 2.5 virginica 102 5.8 2.7 5.1 1.9 virginica 103 7.1 3.0 5.9 2.1 virginica 104 6.3 2.9 5.6 1.8 virginica 105 6.5 3.0 5.8 2.2 virginica

user2547973
  • 343
  • 2
  • 9

3 Answers3

17

If you have Pandoc version >= 2 (bundled with RStudio 1.2) you can use knit_print. I found

cat(knit_print(ft))

successfully printed the tables in a loop.

anotherfred
  • 1,330
  • 19
  • 25
  • 1
    This worked for me; I couldn't pipe into this command though - had to save the table as `x` then `cat(knit_print(x))` – Nova Mar 07 '19 at 16:37
  • 3
    Also don't forget to have results='asis' in code chunk header options for this to work – Isaac Zhao Apr 06 '21 at 16:17
  • Is there a fix for all tables from the loop getting the same number? – BBB Dec 15 '21 at 00:42
4

We often need to loop through data to create subtables in RMarkdown. Here is a straightforward solution for flextable:

```{r, report3, results='asis'}

doThese<-c("setosa","virginica")

for (i in doThese) {
  tbl<-subset(iris, Species==i)
  ft <- flextable(tbl[1:10,])
  flextable_to_rmd(ft)
}
 
```

The key takeaways: set results="asis" for the code chunk, and use flextable_to_rmd function instead of print or cat.

GGAnderson
  • 1,993
  • 1
  • 14
  • 25
  • Looks good, but when I try this instead of `cat(knit_print())` which produced tables with the same number. For example, 5 tables 3.6. Here, the numbers are incremented, but they start at 1 and do not follow numbering of the rest of the document where I had a structure of "section#.table#", as in 3.6 (6th table of section 3). Do you have a solution? – BBB Jan 20 '22 at 21:15
  • Suggest you post this as a separate question, and include your sample code with the method you are using to assign table numbering throughout the document. This loop cannot know how many tables came before it in the document. One approach is to paste content using the text_after parameter in flextable_to_rmd() to manually assign a label. – GGAnderson Jan 26 '22 at 23:50
0

I'm not sure if this is the correct answer but I used this to solve my problem:

Looping through code in knitr and rmarkdown

user2547973
  • 343
  • 2
  • 9