我在R中使用purrr包的map函数,它给出了一个列表输出。现在我希望输出是基于输入的命名列表。下面给出一个例子。
input <- c("a", "b", "c")
output <- purrr::map(input, function(x) {paste0("test-", x)})
从此我想使用以下方法访问列表中的元素:
output$a
或者
output$b
答案 0 :(得分:15)
我们只需要命名list
names(output) <- input
然后根据名称
提取元素output$a
#[1] "test-a"
如果需要使用tidyverse
library(tidyverse)
output <- map(input, ~paste0('test-', .)) %>%
setNames(input)
答案 1 :(得分:2)
可接受的解决方案有效,但是会遇到重复的参数(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
开箱即用地实现这种行为。
答案 2 :(得分:2)
c("a", "b", "c") %>%
purrr::set_names() %>%
purrr::map(~paste0('test-', .))