【问题标题】:R - Combine arbitrary lists element by element with respect to matched namesR - 根据匹配的名称逐个元素地组合任意列表
【发布时间】:2018-07-10 11:10:35
【问题描述】:

我有两个列表

m = list( 'a' = list( 'b' = list( 1, 2 ), 'c' = 3, 'b1' = 4, 'e' = 5 ) )

n = list( 'a' = list( 'b' = list( 10, 20 ), 'c' = 30, 'b1' = 40 ), 'f' = 50 )

m的结构在哪里:

List of 1
 $ a:List of 4
  ..$ b :List of 2
  .. ..$ : num 1
  .. ..$ : num 2
  ..$ c : num 3
  ..$ b1: num 4
  ..$ e : num 5

而n的结构是:

List of 2
 $ a:List of 3
  ..$ b :List of 2
  .. ..$ : num 10
  .. ..$ : num 20
  ..$ c : num 30
  ..$ b1: num 40
 $ f: num 50

想要这样的组合输出。对于深度嵌套的列表,该解决方案也应该是通用的。

预期输出:

List of 2


$ a:List of 4
  ..$ b :List of 4
  .. ..$ : num 1
  .. ..$ : num 2
  .. ..$ : num 10
  .. ..$ : num 20
  ..$ c : num [1:2] 3 30
  ..$ b1: num [1:2] 4 40
  ..$ e : num 5
 $ f: num 50

看过这个,但是对于深度嵌套的列表来说不够通用

R: Combining Nested List Elements by Name

【问题讨论】:

  • 在预期的输出中,为什么“a”列表中的“f”是?
  • "f" 是 n 中的一个元素。因此它被包括在内。
  • 我明白为什么要包含它,我在质疑为什么它与预期输出中的“a”处于同一级别
  • 重点是f应该和a同级。
  • 明白。已更新。

标签: r


【解决方案1】:

这是一种递归方式:

mergeList <- function(x, y){
    if(is.list(x) && is.list(y) && !is.null(names(x)) && !is.null(names(y))){
        ecom <- intersect(names(x), names(y))
        enew <- setdiff(names(y), names(x))
        res <- x
        if(length(enew) > 0){
            res <- c(res, y[enew])
        }
        if(length(ecom) > 0){
            for(i in ecom){
                res[i] <- list(mergeList(x[[i]], y[[i]]))
            }
        }
        return(res)
    }else{
        return(c(x, y))
    }
}

m = list( 'a' = list( 'b' = list( 1, 2 ), 'c' = 3, 'b1' = 4, 'e' = 5 ) )
n = list( 'a' = list( 'b' = list( 10, 20 ), 'c' = 30, 'b1' = 40 ), 'f' = 50 )
mn <- mergeList(m, n)

str(mn)
# List of 2
#  $ a:List of 4
#   ..$ b :List of 4
#   .. ..$ : num 1
#   .. ..$ : num 2
#   .. ..$ : num 10
#   .. ..$ : num 20
#   ..$ c : num [1:2] 3 30
#   ..$ b1: num [1:2] 4 40
#   ..$ e : num 5
#  $ f: num 50

如果您有多个嵌套列表(例如m1m2m3)要合并,Reduce 可能会有所帮助:

Reduce(mergeList, list(m1, m2, m3))

【讨论】:

  • 这很好用。我们可以有一个通用的版本吗?哪里不是 m 和 n,而是 m1、m2、m3、m4、.....等。@mt1022 我们可以扩展一下吗?
  • @SoumyaBoral,你可以用Reduce概括它:Reduce(mergeList, list(m1, m2, m3, ...))
猜你喜欢
  • 2013-09-17
  • 2023-01-28
  • 2017-02-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
相关资源
最近更新 更多