gpt4 book ai didi

r - 如何绑定(bind)两个具有相同结构的列表?

转载 作者:行者123 更新时间:2023-12-04 15:06:13 27 4
gpt4 key购买 nike

介绍

我有两个具有相同结构的嵌套列表,我想组合它们(在 c() 意义上)。

对于这种关系,我在图论或计算机科学中所说的相同结构可能已经存在一个概念,但我不知道。

所以这是我试图澄清我所说的相同结构的意思:

  • 某个级别的列表元素要么全部命名,要么没有命名;
  • 当我们为元素命名时,在该级别永远不会有重复的名称;
  • 当节点本身是命名元素时,两个列表的父子节点关系相同。

  • 所以我想知道是否已经有解决这个问题的方法,我觉得这可能是相当普遍和普遍的......(?)任何解决方案涉及:
  • 使用基础 rapply ;
  • Tidyverse 解决方案与 purrr 的某种组合职能;
  • rlist 中的函数包

  • 会很好!

    例子
    foobar是两个具有相同结构的示例列表。
    wonderful是通过组合 foo 得到的所需列表和 bar (手动完成)。

    我希望它足够清楚!

    # Input lists: foo and bar
    foo <- list(a = list(a1 = 1:3, a2 = rep('a', 3)), b = list(b1 = list(b11 = c(4,5,6), b12 = rep('b', 3)), b2 = list(b21 = list(b31 = c(0, 1, 2)))), c = list(list(c21 = 1:3), list(c21 = 4:6), list(c21 = 7:9)))
    bar <- list(a = list(a1 = 1:3, a2 = rep('z', 3)), b = list(b1 = list(b11 = c(-1,2,5), b12 = rep('b', 3)), b2 = list(b21 = list(b31 = -c(1,2,3)))), c = list(list(c21 = 3:1), list(c21 = 5:3)))

    # wonderful: desired list (result from combining foo and bar)
    wonderful <- list(
    a = list(
    a1 = c(foo$a$a1, bar$a$a1),
    a2 = c(foo$a$a2, bar$a$a2)
    ),
    b = list(
    b1 = list(
    b11 = c(foo$b$b1$b11, bar$b$b1$b11),
    b12 = c(foo$b$b1$b12, bar$b$b1$b12)
    ),
    b2 = list(
    b21 = list(
    b31 = c(foo$b$b2$b21$b31, bar$b$b2$b21$b31)
    )
    )
    ),
    c = c(foo$c, bar$c)
    )

    str(foo)
    #> List of 3
    #> $ a:List of 2
    #> ..$ a1: int [1:3] 1 2 3
    #> ..$ a2: chr [1:3] "a" "a" "a"
    #> $ b:List of 2
    #> ..$ b1:List of 2
    #> .. ..$ b11: num [1:3] 4 5 6
    #> .. ..$ b12: chr [1:3] "b" "b" "b"
    #> ..$ b2:List of 1
    #> .. ..$ b21:List of 1
    #> .. .. ..$ b31: num [1:3] 0 1 2
    #> $ c:List of 3
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 1 2 3
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 4 5 6
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 7 8 9

    str(bar)
    #> List of 3
    #> $ a:List of 2
    #> ..$ a1: int [1:3] 1 2 3
    #> ..$ a2: chr [1:3] "z" "z" "z"
    #> $ b:List of 2
    #> ..$ b1:List of 2
    #> .. ..$ b11: num [1:3] -1 2 5
    #> .. ..$ b12: chr [1:3] "b" "b" "b"
    #> ..$ b2:List of 1
    #> .. ..$ b21:List of 1
    #> .. .. ..$ b31: num [1:3] -1 -2 -3
    #> $ c:List of 2
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 3 2 1
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 5 4 3

    str(wonderful)
    #> List of 3
    #> $ a:List of 2
    #> ..$ a1: int [1:6] 1 2 3 1 2 3
    #> ..$ a2: chr [1:6] "a" "a" "a" "z" ...
    #> $ b:List of 2
    #> ..$ b1:List of 2
    #> .. ..$ b11: num [1:6] 4 5 6 -1 2 5
    #> .. ..$ b12: chr [1:6] "b" "b" "b" "b" ...
    #> ..$ b2:List of 1
    #> .. ..$ b21:List of 1
    #> .. .. ..$ b31: num [1:6] 0 1 2 -1 -2 -3
    #> $ c:List of 5
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 1 2 3
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 4 5 6
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 7 8 9
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 3 2 1
    #> ..$ :List of 1
    #> .. ..$ c21: int [1:3] 5 4 3

    最佳答案

    试一试:

    library(purrr)

    rec_map <- function(fizz, buzz) {
    if(is.atomic(fizz) | is.null(names(fizz))){
    c(fizz, buzz)
    } else {
    imap(fizz,
    ~rec_map(fizz[[.y]], buzz[[.y]]))
    }
    }

    temp <- rec_map(foo, bar)

    all.equal(temp, wonderful)
    #> [1] TRUE

    我绝不是计算机科学家,所以请对解决方案持保留态度。当一层没有名称时,我不确定所需的行为,但随后一层有名称(例如, foo$c)。因此,如果我们遇到没有名称的关卡,我只是合并了结果 ( c())。

    编辑以获取多个列表:
    prec_map <- function(...){
    dots <- list(...)
    first_el = dots[[1]]
    if(is.atomic(first_el) | is.null(names(first_el))){
    do.call(c, dots)
    } else {
    imap(first_el,
    function(el, nme){
    one_level_down <- map(dots, nme)
    do.call(prec_map, one_level_down)
    })
    }
    }

    temp <- prec_map(foo, bar)

    all.equal(temp, wonderful)
    [1] TRUE

    我还没有彻底测试它,但轻量级测试看起来可以完成工作。

    关于r - 如何绑定(bind)两个具有相同结构的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789097/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com