flextable in Rmarkdown docx not printing within if statement if other text
Asked Answered
A

4

13

I'm trying to use the package flextable to get some nicely formatted tables in my Rmarkdown (going to word file). The tables work just fine in general but if I put it within an if statement, if there is anything else being printed from the if statement I don't see the table. Any ideas what's going on?


Update Jan 2020 for any people still looking at this

As of version 0.5.5 of flextable there is a new function docx_value to address this, I have updated the answer to reflect this so that other people don't use the complicated workarounds now there is a simple solution.


My example (run all together) :

---
title: "Testing"
output: 
  word_document:
    reference_docx: styles.docx
---

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

## R Markdown

```{r defaults}
library(pander)
library(knitr)
library(flextable)

```

1st test works fine - no if statement and new lines either side of table

## test 1 table no if statemnets

```{r test1, echo = FALSE, results = 'asis'}

  test <- data.frame (c = 1:5, x = 6:10)

  testft <- flextable(test)
  testft

```

2nd test has an if statement with no other text and works fine

## test 2 if statement no other text

```{r test2, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if(RunTable){

  testft

}

```

But if I try and add other outputs in my if statement, either with or without new line breaks I don't get any table in my output

## test 3 if statement with other text


```{r test3, echo = FALSE, results = 'asis'}
#Hack so dat works up to year 2047 as cpp functions in padr can't handle data beyond 2038 
#Get Daily Values
RunTable <- TRUE
if(RunTable){

    print("before   ")

  testft

    print("after   ")

}

```

## test 4 if statement with other text and newlines


```{r test4, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if(RunTable){

  print("if with linebreak before   ")
  cat("  \n")

  knit_print(testft)

  cat("  \n")

  print("if with linebreak after   ")


}

```

Output: My output

Alleyn answered 31/5, 2019 at 3:3 Comment(0)
A
1

Update Jan 2020 for any people still looking at this

As of version 0.5.5 of flextable there is a new function docx_value to address this, as described in the package news:

flextable 0.5.5

new features

  • new function docx_value to let display flextables from non top level calls inside R Markdown document.
Alleyn answered 30/1, 2020 at 5:59 Comment(1)
I wish to suggest adding a working example to your answer and not just referring to some package to be seached and read throught docmentation, ...Setose
I
4

You can use chunk option results = 'asis' and write the openxml content with format as following

## test 4 if statement with other text and newlines


```{r test4, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if(RunTable){

  print("if with linebreak before   ")
  cat("  \n")

    cat(
      paste(
        "\n```{=openxml}", 
        format(testft, type = "docx"), 
        "```\n", sep = "\n")
    )

  cat("  \n")

  print("if with linebreak after   ")
}

```
Izak answered 3/6, 2019 at 17:42 Comment(0)
M
3

Not sure if you would consider a different package, but this seems to work:

---
title: "Testing"
output: 
  word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, fig.height=1.5, fig.width=3, fig.align='right', fig.align = "center")
```

## R Markdown

```{r defaults}
library(pander)
library(knitr)
library(flextable)
library(tableHTML)

```


## test 1 table no if statemnets

```{r test1, echo = FALSE}

  test <- data.frame (c = 1:5, x = 6:10)
  tab <- tableHTML(test, widths = c(60, 60), rownames = FALSE) %>% add_theme('scientific')

  tab %>% tableHTML_to_image()

```

## test 2 if statement no other text

```{r test2, echo = FALSE}
RunTable <- TRUE
if(RunTable){

  tab %>% tableHTML_to_image()

}

```


```{r test3, echo = FALSE}
#Hack so dat works up to year 2047 as cpp functions in padr can't handle data beyond 2038 
#Get Daily Values
RunTable <- TRUE
if(RunTable){

  print("before   ")

  tab %>% tableHTML_to_image()

  print("after   ")

}

```

## test 4 if statement with other text and newlines


```{r test4, echo = FALSE}
RunTable <- TRUE
if(RunTable){

  print("if with linebreak before   ")
  cat("  \n")

  tab %>% tableHTML_to_image()

  cat("  \n")

  print("if with linebreak after   ")


}

For example, you can see test 4 as an output:

enter image description here

A couple of notes:

  • You can format the table in the exact way you want.
  • The code produces an image.
Muskeg answered 3/6, 2019 at 10:36 Comment(2)
Hi thanks for the suggestion but I want them to be formatted as a table in word (my automated report is going into another report by someone else so if they want to change something it would be good if they can just do it in place)Alleyn
Sure makes sense :)Muskeg
S
2

I presume your problem is related to this issue. Changing the problematic chunks like this seems to work:

## test 3 if statement with other text

```{r test3, echo = FALSE}
RunTable <- TRUE
if(RunTable){
  text <- c(
    "before   ",
    knit_print(testft),
    "after   "
  )

  asis_output(paste(text, collapse = "\n"))
}
```

## test 4 if statement with other text and newlines

```{r test4, echo = FALSE}
RunTable <- TRUE
if(RunTable){
  text <- c(
    "if with linebreak before   ",
    "  \\newline",
    knit_print(testft),
    "  \\newline\n",
    "if with linebreak after   "
  )

  asis_output(paste(text, collapse = "\n"))
}
```

Regarding the last one:

  • I had to use \\newline to actually insert an extra blank line before the table.
  • I don't know why an extra \n is needed for the blank line after, it wouldn't work for me otherwise.
  • Just to test, I tried adding several \\newline entries, both before and after, but one blank line was the most I could get.
Sturdivant answered 2/6, 2019 at 14:0 Comment(3)
Hmm, that issue says that if you have chunk option results = 'asis' then it should work. As I'm happy to have this set (and do in my example) then it shouldn't be a problem. So question still stands. I haven't had a chance to test your code yet, I wonder if problem would still stand as asis_output is still called within if statement, and the issue says "asis_output() only works in top-level R expressions" which it won't be. I will test and see if its a possible workaround tomorrowAlleyn
Yeah, it's weird. There seems to be a subtle difference between the chunk option and the asis_output function. If you set results='asis' and do something like print("a") you get raw R output without formatting, but not raw text. knit_print for flextable uses asis_output, so the other chunks might not even need the results option.Sturdivant
Thanks, this does work for me despite the issue saying that it only works at the top levelAlleyn
A
1

Update Jan 2020 for any people still looking at this

As of version 0.5.5 of flextable there is a new function docx_value to address this, as described in the package news:

flextable 0.5.5

new features

  • new function docx_value to let display flextables from non top level calls inside R Markdown document.
Alleyn answered 30/1, 2020 at 5:59 Comment(1)
I wish to suggest adding a working example to your answer and not just referring to some package to be seached and read throught docmentation, ...Setose

© 2022 - 2024 — McMap. All rights reserved.