4

I'm trying to create multiple tables using kable from a csv file, but the requirement is that I need to also put an image in the table as per the below image. The entire image needs to be in the left column. Is this possible?

Sample Output

The dataframe looks like this:

df<-data.frame(Amount= c('$25', '$45', '$75'), 
               Rate = c('1%', '1%', '3%'), 
               Location = c('Germany', 'Switzerland', 'England'),
               ImageName= c('GE.png', 'BE.png', 'CE.png'),
               Status = c('Sold','Unsold','Sold')
               )

So far my R code is

---
output: 
  word_document:
    reference_docx: ReferenceDoc.docx
---

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

df<-read.csv('Productdata.csv')
```

```{r loops, echo=F, results='asis'}
library(knitr)
for (i in 1:nrow(df))
{

print(kable(df[i,]))
}
```

Im really not sure how I can enter an image like that in my RMarkdown for WORD.

eipi10
  • 91,525
  • 24
  • 209
  • 285
CuriousBeing
  • 1,592
  • 14
  • 34

2 Answers2

11

Here's an approach using kable, along with kableExtra functions to take care of some of the formatting. So far, I've only been able to render this properly to html. I'll update if I can make this work in Word. In the code below, I used some images I happened to have lying around. Just run the same sprintf function on your original ImageName column to get the appropriate rmarkdown tagging for your images.

---
output:
  html_document:
    df_print: paged
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning=FALSE, message=FALSE)
library(knitr)
library(kableExtra)
library(tidyverse)

#df<-read.csv('Productdata.csv')
df<-data.frame(Amount= c('$25', '$45', '$75'), 
               Rate = c('1%', '1%', '3%'), 
               Location = c('Germany', 'Switzerland', 'England'),
               ImageName= c('GE.png', 'BE.png', 'CE.png'),
               Status = c('Sold','Unsold','Sold')
               )

# Change to names of my local images
df$ImageName =c("mal2.jpg",
                "serenity2.jpg",
                "blue_sun2.jpg")

# Add appropriate rmarkdown tagging
df$ImageName = sprintf("![](%s)", df$ImageName)
```

```{r loops, echo=F, results="asis"}
for (i in 1:nrow(df)) {

  # Select desired row
  d = df[i, ]

  # Change name of ImageName column to Status value
  names(d)[grep("ImageName", names(d))] = as.character(d[["Status"]])

  # Convert data to "long" format
  d = d %>% 
    select(-Status) %>% 
    gather(Product, value, Amount:Location) %>% 
    rename(` ` = value)

  # Render table using kableExtra for formatting
  print(kable(d, format="html") %>% 
          kable_styling(full_width=FALSE) %>% 
          collapse_rows(columns=1, valign="top"))
}
```

And here's what the html output file looks like:

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
1

I think this may bump up against the limits of kable, but here is a very not elegant way to do something similar with htmlTable. Notice that the images are relative to the directory you are running the Rmd from, or you can use links to URLs.

---
output:
  html_document:
    df_print: paged
  word_document:
    reference_docx: ReferenceDoc.docx
---

```{r setup, echo=FALSE, message=FALSE, warning=FALSE, results='asis'}
library(knitr)
library(dplyr)
library(magrittr)
library(htmlTable)

x <- 0
df <- data.frame( Status = c('Sold','Unsold','Sold'),
           Image = c('images/fwhm1.jpg', 'images/ridges-shade.jpg', 'images/sep16-2018.jpg'),
           Amount= c('$25', '$45', '$75'), 
           Rate = c('1%', '1%', '3%'), 
           Location = c('Germany', 'Switzerland', 'England')
           )
df$Image <- sprintf('![](%s){width=150px}', df$Image)

for (i in 1:nrow(df)) {
   x <- t(df[i,])
   new.df <- data.frame(matrix(ncol=2,nrow=2))
   new.df[1,1] <- paste(x[1],x[2],sep="<br>")
   new.df[1,2] <- paste0(rownames(x)[3:5], ": ", x[3:5], collapse="<br>")
   colnames(new.df) <- NULL
   rownames(new.df) <- NULL
   print( htmlTable(new.df, 
      css.cell="padding-left: .5em; padding-right: .5em; align: left; align: left; vertical-align: top;",
   rnames=FALSE) )
}
```

Here is what it looks like:

enter image description here

I also opened the HTML file that was rendered in Word, and was able to shrink the images and add borders -- the table structure was retained. It looked like this:

enter image description here

mysteRious
  • 4,102
  • 2
  • 16
  • 36
  • Thank you for your input. I would really love this exact same output in WORD. Is that possible? – CuriousBeing Oct 21 '18 at 23:28
  • Possible, yes, but that would require a different kind of solution. The `kable` and `htmlTable` do better with HTML, and packages like `flextable` do better with rendering tables to Word and PDF in my opinion. Would recommend that you repost a new question, maybe include my solution as a starting point, then specifically request to find a Word solution. Good luck :) – mysteRious Oct 22 '18 at 00:37
  • Thanks again. But my question does say it needs to be WORD (last sentence). I will wait a bit more time, then will repost if no one sees it. – CuriousBeing Oct 22 '18 at 00:57
  • 1
    Oh! That was waaaaaaay down there at the bottom. Sorry for missing it. – mysteRious Oct 22 '18 at 01:25
  • I just tried using Word to open the HTML file that can be rendered from the code above. Except for having to shrink the images, the table structure was retained and it was also easy to add borders. I added the screen shot above. – mysteRious Oct 22 '18 at 02:03
  • You have been a major help! Thank you – CuriousBeing Oct 22 '18 at 09:34