Gandalf_the_Green
Gandalf_the_Green

Reputation: 80

Mapping different args to a list of data frames

This might be a job for Purr or maybe I just need to change the layout of my function or my data here.

I've got a function that takes 2 arguments which I'm trying to apply across a list of data frames. One of the arguments should be the list element (the name) name whereas the other will be a list component (a value in the list).

Book List - Book title and Chapters

my_list <- list(Book1 = c("ABC", "DEF", "GHI"), Book2 = c("ABB", "BCC"), Book3 = c("AAA", "BBB", "CCC", "DDD")) 

Function with arg for list component and value

my_function <- function(Book, Chapter) {

path <-  paste("www.fake-website.com", "ctp:", Book, "/", Chapter, sep = "")

  ##Would have API call here, but let's just print path
  path     
}

I can easily call this on an individual item by specifying the arguments in map

map(my_list$Book1, function(Chapter) my_function(Chapter =   
Chapter, Book = "Book1"))

Output:

[[1]]
[1] "www.fake-website.comctp:Book1/ABC"

[[2]]
[1] "www.fake-website.comctp:Book1/DEF"

[[3]]
[1] "www.fake-website.comctp:Book1/GHI"

But How do I apply the function to each list element, calling the function to each Book name and the chapter values?

I'm hoping for something like

[[1]]
[1] "www.fake-website.comctp:Book1/ABC"

[[2]]
[1] "www.fake-website.comctp:Book1/DEF"

[[3]]
[1] "www.fake-website.comctp:Book1/GHI"

[[4]]
[1] "www.fake-website.comctp:Book2/ABB"

[[5]]
[1] "www.fake-website.comctp:Book2/BCC"

[[6]]
[1] "www.fake-website.comctp:Book2/AAA"

[[7]]    
[1] "www.fake-website.comctp:Book2/BBB"

[[8]]    
[1] "www.fake-website.comctp:Book2/CCC"

[[9]]    
[1] "www.fake-website.comctp:Book2/DDD"

My function actually isn't simply pasting Books and Chapters, but getting a bunch of info from the API and parsing it.

However, what I need help with is mapping across the list of data frames and pairing the book arg with the chapter arg.

Upvotes: 0

Views: 38

Answers (1)

akuiper
akuiper

Reputation: 214957

You can use purrr::imap, which passes the names of the list as second argument to the function:

library(purrr)
imap(my_list, ~ my_function(..2, ..1))
# or imap(my_list, ~ my_function(.y, .x))

$Book1
[1] "www.fake-website.comctp:Book1/ABC" "www.fake-website.comctp:Book1/DEF"
[3] "www.fake-website.comctp:Book1/GHI"

$Book2
[1] "www.fake-website.comctp:Book2/ABB" "www.fake-website.comctp:Book2/BCC"

$Book3
[1] "www.fake-website.comctp:Book3/AAA" "www.fake-website.comctp:Book3/BBB"
[3] "www.fake-website.comctp:Book3/CCC" "www.fake-website.comctp:Book3/DDD"

And if you switch the arguments of your function, Book and Chapter, you can simply do:

my_function <- function(Chapter, Book) {
    path <-  paste("www.fake-website.com", "ctp:", Book, "/", Chapter, sep = "")
    path     
}

imap(my_list, my_function)

$Book1
[1] "www.fake-website.comctp:Book1/ABC" "www.fake-website.comctp:Book1/DEF"
[3] "www.fake-website.comctp:Book1/GHI"

$Book2
[1] "www.fake-website.comctp:Book2/ABB" "www.fake-website.comctp:Book2/BCC"

$Book3
[1] "www.fake-website.comctp:Book3/AAA" "www.fake-website.comctp:Book3/BBB"
[3] "www.fake-website.comctp:Book3/CCC" "www.fake-website.comctp:Book3/DDD"

Upvotes: 2

Related Questions