Is it possible for map() to return a named list from unnamed input?

In trying to come up with a solution for How can I use map*() to eliminate repeated calls to mutate()?, I kept getting errors when I tried use map*() functions to create a named list or vector.

For example, suppose I wanted to have the named list:

list("a" = 1, "b" = 2, "c" = 3)

be the output of a map*() function applied to the vector c("a", "b", "c"). How would I do that? Is it possible?

Hi @dromano,

the only way i see replicating the behavior of mapply

a <- c("a", "b", "c")
b <- 1:3
res <- mapply(FUN = function(x,y){
  y
  },
  a,
  b, 
  USE.NAMES = TRUE, 
  SIMPLIFY = FALSE
)

is calling set_names

purrr::map(.x = b, .f = \(x){x}) |> purrr::set_names(a)

i doubt that there is a purrr way to do it in one single map* call.

1 Like

@dromano, I'm not sure if it addresses your issue, but I added an answer to the original question.

1 Like

This seems to be the case since map*() applies the names of the input vector to the output vector:

library(tidyverse)
letters[1:3] |> 
  # add values as names of same vector, and 
  # follow with magrittr pipe to use '.' placeholder
  set_names() %>% 
  # extract indices of names
  map2(
    seq_along(.),
    \(name, idx) idx
    )
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2
#> 
#> $c
#> [1] 3

Created on 2024-05-29 with reprex v2.0.2

I don't see how to simplify this further.

Not directly, but thanks for all the food for thought! Your use of imap() there suggested the use map2() here: