2

I'm trying to add several images to a dataframe in R to reproduce in R Shiny as DT::dataTableOutput.

The desired output would look something like:

Icon Food
First grapes
Second marrow

I fount this question Adding an image to a datatable in R which allows me to add images that I have locally, however only if I type in the path, as such:


df <- read.csv("data.csv")

path = "/Users/name/Documents/remaining_path/"

df%<>%
  mutate(Icon = img_uri("/Users/name/Documents/remaining_path/grapes.png"))

However I have hundreds of images to add so I was hoping to get something slightly more automated, like this:


df%<>%
  mutate(Image = paste(path, Food, ".png", sep = ""))%>%
  mutate(Icon = img_uri(Image))

which gives me this error

Error in `mutate()`:
! Problem while computing `Icon = img_uri(Image)`.
Caused by error in `file()`:
! invalid 'description' argument

I have also tried creating a vector with a for loop:


for (i in df$Image) {
  
  Icon <- img_uri(i)
  
}

which throws this error

Error in file(con, "rb") : cannot open the connection

9. file(con, "rb")
8. readBin(file, what, n, ...)
7. read_bin(x)
6. base64_encode(x)
5. paste0("data:", mime::guess_type(x), ";base64,", base64_encode(x))
4. xfun::base64_uri(f)
3. knitr::image_uri(x)
2. sprintf("<img src=\"%s\"/>", knitr::image_uri(x))
1. img_uri(i)

And with apply:

Icon <- apply(X = df$Image, MARGIN = 1, FUN = img_uri())

which gives this error

Error in knitr::image_uri(x) : argument "x" is missing, with no default

9. basename(file)
8. mime::guess_type(x)
7. paste0("data:", mime::guess_type(x), ";base64,", base64_encode(x))
6. xfun::base64_uri(f)
5. knitr::image_uri(x)
4. sprintf("<img src=\"%s\"/>", knitr::image_uri(x))
3. img_uri()
2. match.fun(FUN)
1. apply(X = df$Image, MARGIN = 1, FUN = img_uri())

Would appreciate any input on this.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
Seni
  • 93
  • 1
  • 8

1 Answers1

2

I would do:

library(DT)
library(base64enc)

imgs <- c("img1.png", "img2.png")
b64imgs <- vapply(imgs, function(img){
  dataURI(mime = "image/png", file = img)
}, character(1L))
b64array <- paste0(
  c("[", sprintf("%s", toString(paste0("'", b64imgs, "'"))), "]"), 
  collapse = ""
)

render <- c(
  "function(data, type, row){",
  "  if(type === 'display'){",
  sprintf("var img = %s[data-1];", b64array),
  "    data = '<img src=\"' + img + '\"  width=100>';",
  "  }",
  "  return data;",
  "}"
)

dat <- data.frame(
  image = c(1, 2), 
  file = imgs
)

datatable(
  dat, 
  width = 500,
  options = list(
    columnDefs = list(
      list(targets = 1, render = JS(render)),
      list(targets = "_all", className = "dt-center")
    )
  )
)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225