Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Kable Tables with Images

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.

like image 503
CuriousBeing Avatar asked Sep 04 '25 03:09

CuriousBeing


2 Answers

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

like image 154
eipi10 Avatar answered Sep 05 '25 18:09

eipi10


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

like image 20
mysteRious Avatar answered Sep 05 '25 16:09

mysteRious