Используйте ввод функции purrr map для создания именованного списка в качестве вывода в R
Я использую функцию отображения пакета purrr в R, которая дает в качестве вывода список. Теперь я хотел бы, чтобы выход был именованным списком на основе ввода. Пример приведен ниже.
input <- c("a", "b", "c")
output <- purrr::map(input, function(x) {paste0("test-", x)})
Из этого я хотел бы получить доступ к элементам списка, используя:
output$a
или
output$b
Ответы
Ответ 1
Нам просто нужно назвать list
names(output) <- input
а затем извлеките элементы на основе имени
output$a
#[1] "test-a"
Если это нужно сделать, используя tidyverse
library(tidyverse)
output <- map(input, ~paste0('test-', .)) %>%
setNames(input)
Ответ 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
реализовал такое поведение из коробки.