M_M
M_M

Reputation: 909

r dplyr - read list of files and use filename as a variable

I would like to replace the "Text" below in image_annotate by the name of each file.

library(dplyr)
library(purrr)
library(magick)

list.files(path = "", pattern = "*.png", full.names = T) %>% 
      map(image_read) %>%
      lapply(. %>% image_annotate("Text")) %>%
      image_join() %>% 
      image_animate(fps=1) %>% 
      image_write("animated.gif")

Upvotes: 4

Views: 3095

Answers (2)

Tino
Tino

Reputation: 2101

I think that this should work. Since you get the information about the filename and pass it to the image_read but want to use this information also for another function (image_annotate), you can easily put the two in a function within map. If you don't want the whole path as annotation, just replace image_annotate(fnme) by image_annotate(stringr::str_extract(string = fnme, pattern = "(?<=(/|\\\\)).+(?=\\.png)")) which matches anything between / or \ and .png (assuming that you don't want the ending, else just remove the lookahead (?=\\.png).

library(dplyr)
library(purrr)
library(magick)

list.files(path = "", pattern = "*.png", full.names = T) %>% 
      map(function(fnme) {
          image_read(fnme) %>% image_annotate(fnme)
      }) %>%
      image_join() %>% 
      image_animate(fps=1) %>% 
      image_write("animated.gif")

Upvotes: 3

Kevin Arseneau
Kevin Arseneau

Reputation: 6264

The lapply won't work in your piped chain because image_annotate won't accept more than one value. You can use a vector of the names and map2 from purrr.

path <- ""
pattern <- "*.png"    

file_name <- list.files(path, pattern, full.names = FALSE) %>%
  tools::file_path_sans_ext()

list.files(path, pattern, full.names = TRUE) %>% 
  map(image_read) %>%
  map2(file_name, image_annotate) %>%
  image_join() %>% 
  image_animate(fps = 1) %>% 
  image_write("animated.gif")

Edit

If you prefer the full path file names included in the image_annotate, you could forego the vector assignment preceding the pipe and add an assign inline.

list.files(path, pattern, full.names = T) %>%
  assign("file_name", value = ., pos = 1) %>%
  map(image_read) %>%
  map2(file_name, image_annotate) %>%
  image_join() %>% 
  image_animate(fps = 1) %>% 
  image_write("animated.gif")

Upvotes: 3

Related Questions