使用 purrr 的 map 函数的输入创建一个命名列表作为 R 中的输出

Use input of purrr's map function to create a named list as output in R

我正在使用 R 中 purrr 包的 map 函数,它给出一个列表作为输出。现在我希望输出是基于输入的命名列表。下面给出一个例子。

input <- c("a", "b", "c")
output <- purrr::map(input, function(x) {paste0("test-", x)})

由此我想使用以下方式访问列表的元素:

output$a

或者

output$b

我们只需要命名 list

names(output) <- input

然后根据名称提取元素

output$a
#[1] "test-a"

如果需要使用 tidyverse

library(tidyverse)
output <- map(input, ~paste0('test-', .)) %>% 
                                setNames(input)

更新

现在在 2020 年,@mihagazvoda 的回答表描述了正确的方法:在应用 map

之前简单地 set_names
c("a", "b", "c") %>% 
    purrr::set_names() %>% 
    purrr::map(~paste0('test-', .))

过时的答案

接受的解决方案有效,但存在重复参数 (input) 的问题,这可能会导致错误并在使用带有 %>% 的管道时中断流程。

另一种解决方案是使用更强大的 %>% 运算符

1:5 %>% { set_names(map(., ~ .x + 3), .) } %>% print # ... or something else

这从管道中提取了参数,但仍然缺乏一些美感。一个替代方法可能是一个小的辅助方法,例如

map_named = function(x, ...) map(x, ...) %>% set_names(x)

1:5 %>% map_named(~ .x + 1)

这已经看起来更加漂亮和优雅了。这将是我的首选解决方案。

最后,如果参数是字符或整数向量,我们甚至可以覆盖 purrr::map,并在这种情况下生成命名列表。

map = function(x, ...){
    if (is.integer(x) | is.character(x)) {
        purrr::map(x, ...) %>% set_names(x)
    }else {
        purrr::map(x, ...) 
    }
}

1 : 5 %>% map(~ .x + 1)

但是,最佳解决方案是 purrr 开箱即用。

The recommended solution:

c("a", "b", "c") %>% 
    purrr::set_names() %>% 
    purrr::map(~paste0('test-', .))