rms-wordr-markdownknitrr-flextable

Adding image to flextable to be generated with knitr fails but works in RMarkdown chunk


Running R4.1.2 and Windows 10:

I'm trying to knit a document that has a flextable with a ggplot image that was created via ggsave. When I run the code chunk in RMarkdown, it works fine, but when I attempt to knit a word document, I get the following error. If I don't include the image, knitr works fine.


    Quitting from lines 350-376 (RPOPS_Draft_Test2.0.Rmd) 
    Error in read_xml.raw(charToRaw(enc2utf8(x)), "UTF-8", ..., as_html = as_html,  : 
      xmlParseEntityRef: no name [68]
    Calls: <Anonymous> ... as_xml_document -> as_xml_document.character -> read_xml.raw
    
    Execution halted

Below are the yaml headers. I am using officedown, as I know this package is required to have images in flextables be rendered in Word.


    ---
    title: "something: `r params$program`"
    output:
      officedown::rdocx_document: 
        reference_docx: P:/Reference_doc
    params:
      program: "something"
    ---

And here is the code chunk causing the issue.


    ```{r overall1_flextable}
    
    # chart creation
    plot_overall1 <- f_overall_cht(overall_chart1)
    plot_overall1_img_out <- ggsave(filename = "plotoverall1img.png", plot = plot_overall1, width = 3.05, height = 0.37, dpi = 600, device = "png")
    
    plot_overall1_in <- file.path(getwd(), "plotoverall1img.png")
    
    example_tibble <- tibble(
      col_name = "chart to the right",
      chart = ""
    )
    
    ft <- flextable(example_tibble)
    
    ft <- compose(ft, i=1, j=2,
                  value = as_paragraph(
                    as_image(src = plot_overall1_in, width = 3.05, height = 0.37),
                    as_chunk(chart)),
                  part = "body"
                  )
    
    autofit(ft)
    ```

Solution

  • I could not reproduce your error. Below the code to produce your table. There are two solutions, my recommended solution (documented here: https://ardata-fr.github.io/flextable-book/cell-content-1.html#base-plots-and-ggplot-objects) and something closer to what you wrote.

    
    ---
    title: "test"
    output: officedown::rdocx_document
    ---
    
    ```{r setup, include=FALSE}
    library(officedown)
    library(officer)
    library(flextable)
    library(ggplot2)
    library(tibble)
    # chart creation
    plot_overall1 <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
      geom_point()+
      theme_void()
    ```
    
    ## Recommanded 
    
    
    The solution below is corresponding to the recommanded way.
    
    ```{r}
    example_tibble <- tibble(
      col_name = "chart to the right",
      chart = list(plot_overall1)
    )
    
    ft <- flextable(example_tibble)
    
    ft <- compose(ft,
      j = "chart",
      value = as_paragraph(
        gg_chunk(value = chart, width = 3.05, height = 0.37, unit = "in")
      ),
      part = "body"
    )
    
    autofit(ft)
    ```
    
    
    ## From scratch 
    
    The solution below is corresponding to the way you tried.
    
    ```{r}
    png_file <- tempfile(fileext = ".png")
    
    plot_overall1_img_out <- ggsave(
      filename = png_file, 
      plot = plot_overall1, 
      width = 3.05, height = 0.37, 
      dpi = 600, device = "png")
    
    example_tibble <- tibble(
      col_name = "chart to the right"
    )
    
    ft <- flextable(example_tibble,
                    col_keys = c("col_name", "chart"))
    
    ft <- compose(ft,
      i = 1, j = "chart",
      value = as_paragraph(
        as_image(src = png_file, width = 3.05, height = 0.37, unit = "in")
      ),
      part = "body"
    )
    
    autofit(ft)
    ```
    
    
    
    

    enter image description here