Search code examples
rmarkdown

How to put an image from Knitr & a flextable side-by-side in RMarkdown HTML doc


I have an image that I need to grab from the internet and I need to place it to the side of a flextable. My closest attempt is as follows:

library(knitr)
library(dplyr)
library(grid)
library(gridExtra)

url <- "https://static1.cbrimages.com/wordpress/wp-content/uploads/2021/02/rickroll-header.jpg?q=50&fit=contain&w=1140&h=&dpr=1.5"
mrRick <- knitr::include_graphics(url)

myTable <- data.frame(Test = c(1,2,3,4,5),
                      Test2 = c(1,2,3,4,5)) %>%
  flextable()

grid.arrange(rasterGrob(mrRick), gen_grob(myTable))

Unfortunately this gives me the error no applicable method for 'as.raster' applied to an object of class "c('knit_image_paths', 'knit_asis')" and I'm not sure how to go about fixing this. I am open to using other packages to download the image or to arrange the table and image together.


Solution

  • Putting this in a knitr chunk seems to work for me:

    library(knitr)
    library(flextable)
    library(dplyr)
    library(grid)
    library(gridExtra)
    library(png)
    
    url <- "https://static1.cbrimages.com/wordpress/wp-content/uploads/2021/02/rickroll-header.jpg?q=50&fit=contain&w=1140&h=&dpr=1.5"
    tf <- tempfile(fileext = '.jpg')
    
    download.file(url, destfile = tf, mode = "wb")
    
    myTable <- data.frame(Test = c(1,2,3,4,5),
                          Test2 = c(1,2,3,4,5)) |>
      flextable()
    
    jpeg::readJPEG(tf) |>
      rasterGrob() |>
      list(gen_grob(myTable)) |>
      marrangeGrob(ncol = 2, nrow = 1)
    
    

    I obtain output that looks like this:

    Example of output using grobs

    A second option is side by side divs in HTML in your Rmd (the code below assumes you've saved the file path in tf:

    ```{r fig.width=4, fig.height=6,echo=FALSE,out.extra='style="float:left"'}
    knitr::include_graphics(tf)
    
    ```
    
    ```{r echo=FALSE, out.extra='style="float:left"'}
    data.frame(Test = c(1,2,3,4,5),
                          Test2 = c(1,2,3,4,5)) |>
      flextable()
    ```
    
    <div style="clear: both;"></div>
    
    

    which will look like this: Example of output using side-by-side divs