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

Sarah
  • 3,022
  • 1
  • 19
  • 40

4 Answers4

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   ")
}

```
David Gohel
  • 9,180
  • 2
  • 16
  • 34
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.
LyzandeR
  • 37,047
  • 12
  • 77
  • 87
  • 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) – Sarah Jun 05 '19 at 23:58
  • Sure makes sense :) – LyzandeR Jun 06 '19 at 09:33
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.
Alexis
  • 4,950
  • 1
  • 18
  • 37
  • 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 tomorrow – Sarah Jun 03 '19 at 04:22
  • 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. – Alexis Jun 03 '19 at 05:00
  • Thanks, this does work for me despite the issue saying that it only works at the top level – Sarah Jun 06 '19 at 04:58
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.
Sarah
  • 3,022
  • 1
  • 19
  • 40