Suppose I have a list of named vectors:
test_list <- list("grp1" = c(subgrp1 = "A", subgrp2 = "B"),
"grp2" = c(subgrp1 = "A", subgrp2 = "B"),
"grp3" = c(subgrp1 = "A"))
I want to change this into
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 list of length 5, but loses the "grp" hierarchy completely - which isn't surprising since that's the point of this function. I wish to "maintain" the hierarchy by keeping the name on those with length of >1.
I suppose you can rename each elements in named vector based on the layer above... but I am not sure how to do this operation in scalable manner when the list has varying length.
How can I approach this problem?
CodePudding user response:
We may need some modification by changing the names
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))))
-checking with expected output
> all.equal(want_list, want_list2)
[1] TRUE
Or using flatten
and tidyverse options
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
-testing
> all.equal(want_list, want_list3)
[1] TRUE