R(purrr)展平命名列表以列出并保留名称 [英] R (purrr) flatten list of named lists to list and keep names

查看:50
本文介绍了R(purrr)展平命名列表以列出并保留名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我遗漏了一些明显的东西,但试图将R中的命名列表的命名列表的列表(甚至可能更多地嵌套)展平为最终一个展平列表. purrr rlist 似乎都有相应的工具.我如何才能实现子列表的名称成为平坦结果列表的名称预加密,例如 purrr 中的 list1.blist.a ?我的实际列表更深入地嵌套了不同数量的级别,并在不同级别上重复了名称.最后,我执行 purrr :: map_df(final_list,bind_rows),这似乎删除了所有重复的名称(即使我不知道原来的重复名称来自哪个分支,从).我可以使用 rlist 来做到这一点,但我一直希望有一个 tidyverse 解决方案(没有什么能与出色的 rlist 媲美的,但是很多人已经有了 tidyverse ).

Maybe I'm missing something obvious but trying to flatten a list of named lists of named lists in R (may even be more nested) into eventually one flat list. purrr and rlist seem to have tools for that. How can I achieve that names of sublists become name precrypts of flattened result list, e.g. list1.blist.a in purrr? My actual list is more deeply nested with varying number of levels and repeating names on different levels. In the end I perform purrr::map_df(final_list, bind_rows) and this seems to drop all duplicate names (and even if it didn't I don't know from which branch the original duplicate name comes from). I can do it with rlist but I had hoped for a tidyverse solution (nothing against fantastic rlist but many already have tidyverse installed).

还请注意, rlist :: list.flatten()会始终删除除顶部之外的所有级别,而 purrr :: flatten()会一次删除一级有时可能是您所需要的.您可以根据需要多次嵌套purrr :: map(.x,.f = rlist :: list.flatten)来实现相同的目的,但这很麻烦并且不美观/不可读.

Also note that rlist::list.flatten() will always remove all levels but the top while purrr::flatten() drops levels one at a time which may sometimes be what you need. You could achieve the same by nesting purrr::map(.x, .f = rlist::list.flatten) as often as you require but it's cumbersome and not beautiful/readable.

alist <- list(list1 = list(a = 1, b = 2, blist = list(a = 3, b = 4)),
              list2 = list(a = 1, b = 2, blist = list(a = 3, b = 4)))
str(alist)

List of 2
 $ list1:List of 3
  ..$ a    : num 1
  ..$ b    : num 2
  ..$ blist:List of 2
  .. ..$ a: num 3
  .. ..$ b: num 4
 $ list2:List of 3
  ..$ a    : num 1
  ..$ b    : num 2
  ..$ blist:List of 2
  .. ..$ a: num 3
  .. ..$ b: num 4

alist_flat <- purrr::map(alist, purrr::flatten)
str(alist_flat)

List of 2
 $ list1:List of 4
  ..$ a: num 1
  ..$ b: num 2
  ..$ a: num 3
  ..$ b: num 4
 $ list2:List of 4
  ..$ a: num 1
  ..$ b: num 2
  ..$ a: num 3
  ..$ b: num 4

alist_flattest <- purrr::flatten(alist_flat)
str(alist_flattest)

List of 8
 $ a: num 1
 $ b: num 2
 $ a: num 3
 $ b: num 4
 $ a: num 1
 $ b: num 2
 $ a: num 3
 $ b: num 4

# works with rlist
alist_flat_names <- map(alist, rlist::list.flatten, use.names = TRUE)
str(alist_flat_names)

List of 2
 $ list1:List of 4
  ..$ a      : num 1
  ..$ b      : num 2
  ..$ blist.a: num 3
  ..$ blist.b: num 4
 $ list2:List of 4
  ..$ a      : num 1
  ..$ b      : num 2
  ..$ blist.a: num 3
  ..$ blist.b: num 4

alist_flattest_names <- rlist::list.flatten(alist_flat_names, use.names = TRUE)
str(alist_flattest_names)

List of 8
 $ list1.a      : num 1
 $ list1.b      : num 2
 $ list1.blist.a: num 3
 $ list1.blist.b: num 4
 $ list2.a      : num 1
 $ list2.b      : num 2
 $ list2.blist.a: num 3
 $ list2.blist.b: num 4

推荐答案

我查看了rlist :: list.flatten()的源代码,并将源代码复制到一个新函数中以避免这种依赖性.

I looked at the source for rlist::list.flatten() and copied the source into a new function to avoid that dependency.

my_flatten <- function (x, use.names = TRUE, classes = "ANY") 
{
  #' Source taken from rlist::list.flatten
  len <- sum(rapply(x, function(x) 1L, classes = classes))
  y <- vector("list", len)
  i <- 0L
  items <- rapply(x, function(x) {
    i <<- i + 1L
    y[[i]] <<- x
    TRUE
  }, classes = classes)
  if (use.names && !is.null(nm <- names(items))) 
    names(y) <- nm
  y
}

alist <- list(list1 = list(a = 1, b = 2, blist = list(a = 3, b = 4)),
              list2 = list(a = 1, b = 2, blist = list(a = 3, b = 4)))


flat_list <- my_flatten(alist)

str(flat_list)


结果:

List of 8
 $ list1.a      : num 1
 $ list1.b      : num 2
 $ list1.blist.a: num 3
 $ list1.blist.b: num 4
 $ list2.a      : num 1
 $ list2.b      : num 2
 $ list2.blist.a: num 3
 $ list2.blist.b: num 4

这篇关于R(purrr)展平命名列表以列出并保留名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆