purrr::flatten 一个列表但保留层次名称
purrr::flatten a list but maintain the hierarchy name
假设我有一个命名向量列表:
test_list <- list("grp1" = c(subgrp1 = "A", subgrp2 = "B"),
"grp2" = c(subgrp1 = "A", subgrp2 = "B"),
"grp3" = c(subgrp1 = "A"))
我想把这个改成
want_list <- list("grp1 - subgrp1" = c(subgrp1 = "A"),
"grp1 - subgrp2" = c(subgrp2 = "B"),
"grp2 - subgrp1" = c(subgrp1 = "A"),
"grp2 - subgrp2" = c(subgrp2 = "B"),
"grp3" = c(subgrp1 = "A"))
purrr::flatten(test_list)
returns 长度为 5 的列表,但完全失去了“grp”层次结构——这并不奇怪,因为这是此函数的重点。我希望通过将名称保留在长度 >1 的名称上来“维护”层次结构。
我想你可以根据上面的层重命名命名向量中的每个元素...但我不确定当列表长度不同时如何以可扩展的方式执行此操作。
我该如何解决这个问题?
我们可能需要通过更改名称进行一些修改
want_list2 <- do.call(c, unname(Map(function(x, y) {
lst1 <- lapply(seq_along(x), function(i) x[i])
if(length(lst1) > 1)
setNames(lst1, paste0(y, ' - ', names(x))) else setNames(lst1, y)
}, test_list, names(test_list))))
-检查预期输出
> all.equal(want_list, want_list2)
[1] TRUE
或使用 flatten
和 tidyverse 选项
library(dplyr)
library(purrr)
library(stringr)
want_list3 <- imap(test_list, ~
map(as.list(seq_along(.x)), function(i) .x[i]) %>%
set_names(if(length(.x) > 1) str_c(.y, ' - ', names(.x)) else
.y)) %>%
flatten
-测试
> all.equal(want_list, want_list3)
[1] TRUE
假设我有一个命名向量列表:
test_list <- list("grp1" = c(subgrp1 = "A", subgrp2 = "B"),
"grp2" = c(subgrp1 = "A", subgrp2 = "B"),
"grp3" = c(subgrp1 = "A"))
我想把这个改成
want_list <- list("grp1 - subgrp1" = c(subgrp1 = "A"),
"grp1 - subgrp2" = c(subgrp2 = "B"),
"grp2 - subgrp1" = c(subgrp1 = "A"),
"grp2 - subgrp2" = c(subgrp2 = "B"),
"grp3" = c(subgrp1 = "A"))
purrr::flatten(test_list)
returns 长度为 5 的列表,但完全失去了“grp”层次结构——这并不奇怪,因为这是此函数的重点。我希望通过将名称保留在长度 >1 的名称上来“维护”层次结构。
我想你可以根据上面的层重命名命名向量中的每个元素...但我不确定当列表长度不同时如何以可扩展的方式执行此操作。
我该如何解决这个问题?
我们可能需要通过更改名称进行一些修改
want_list2 <- do.call(c, unname(Map(function(x, y) {
lst1 <- lapply(seq_along(x), function(i) x[i])
if(length(lst1) > 1)
setNames(lst1, paste0(y, ' - ', names(x))) else setNames(lst1, y)
}, test_list, names(test_list))))
-检查预期输出
> all.equal(want_list, want_list2)
[1] TRUE
或使用 flatten
和 tidyverse 选项
library(dplyr)
library(purrr)
library(stringr)
want_list3 <- imap(test_list, ~
map(as.list(seq_along(.x)), function(i) .x[i]) %>%
set_names(if(length(.x) > 1) str_c(.y, ' - ', names(.x)) else
.y)) %>%
flatten
-测试
> all.equal(want_list, want_list3)
[1] TRUE