In the tidyverse, how can I get the number of the current iteration in purrr::walk?

Viewed 37

I'm trying to use purrr to iterate the rows of a tibble. One of the columns of the tibble is itself a comma delimited string over which I also need to iterate, which I am doing with a helper function.

For context, what I'm really trying to do is download products' images by their URL and name them by their model number. However, I understand it to be bad form to have others run code which performs a download, so I think the string construction below would serve as an equivalent example conceptually, just with print statements instead of downloads.

A reprex:

library(tidyverse)
df1 <- tibble(
  name = c("ModelA", 
           "ModelB"),
  urls = c("URL_A", 
           "URL_B1, URL_B2")
)

make_string <- function(name, string_list){
  string_list %>% 
    str_split(", ") %>% 
    unlist() %>% 
    walk(~(
      # This will be a download.file statment in my actual case.
      print(str_c(name, " has a file at ", .x, " and will have filename ", name, "(WHAT GOES HERE?).jpg"))
    ))
}

df1 %>%
  walk2(.x = .$name,
        .y = .$urls,
        .f = ~make_string(.x, .y)
          )
#> [1] "ModelA has a file at URL_A and will have filename ModelA(WHAT GOES HERE?).jpg"
#> [1] "ModelB has a file at URL_B1 and will have filename ModelB(WHAT GOES HERE?).jpg"
#> [1] "ModelB has a file at URL_B2 and will have filename ModelB(WHAT GOES HERE?).jpg"

Created on 2022-04-05 by the reprex package (v2.0.1)

The problem is that the file names for the Model B files will be identical, and I will need them to be distinct. My thought is to append the number (index?) of the current iteration of the walk statement, but I have no idea how to do that.

If I can get code that produces as output:

#> [1] "Model A has a file at URL_A and will have filename ModelA-1.jpg"
#> [1] "Model B has a file at URL_B1 and will have filename ModelB-1.jpg"
#> [1] "Model B has a file at URL_B2 and will have filename ModelB-2.jpg"

then I expect that I can adapt it to perform the downloading and naming I will need.

How can I do this?

1 Answers

I should have guessed. iwalk did the trick.

make_string <- function(name, string_list){
  string_list %>% 
    str_split(", ") %>% 
    unlist() %>% 
    iwalk(~(
      print(str_c(name, " has a file at ", .x, " and will have filename ", name, "-", .y, ".jpg"))
    ))
}

Related