【问题标题】:R flatten out list hierarchy to matrix or data.frameR将列表层次结构展平为矩阵或data.frame
【发布时间】:2012-09-27 21:36:29
【问题描述】:

我想将列表层次结构(类似于 JSON)展平为矩阵或数据框。假设我创建了以下列表:

a <- list(
  b1 = list(
     c1 = list(
       d1 = data.frame()
     ),
     c2 = data.frame()
  ),
  b2 = data.frame()
)

每个字母是另一个级别或降低层次结构。然后我想要一个功能,例如listToMatrix(mylist = a, steps = 2),生成以下内容:

    [,1] [,2]
[1,] "b1" "c1"
[2,] "b1" "c2"
[3,] "b2" "b2"

请注意,函数的参数steps = 2 暗示它应该只在层次结构中下降 2 步。此外,如果在一个方向上没有足够的级别可用,请参阅b2,那么它应该在矩阵中保留前一个列表名称。

有什么建议吗? :)

【问题讨论】:

  • 有趣。某种递归应用可能会做到这一点。
  • 只是为了确定:输出矩阵包含列表名称,而不是数据本身?我们可以假设嵌套列表都有名字吗?
  • @flodel:确切地说,矩阵包含列表名称。在我的示例中,它们都将具有名称。在我将应用它的地方,底层(d1、c2、b2、...)实际上将以data.frame 的形式存储数据,而不是空的list()
  • @AriB.Friedman:我认为你是对的,在我发现类似问题之前:http://r.789695.n4.nabble.com/How-to-flatten-a-tree-based-on-list-to-a-certain-depth-td1461535.html,但是我无法在我的示例中应用相同的解决方案。我在递归中有点迷失了......

标签: r list matrix


【解决方案1】:

这里有一个解决方案。所以它在这里很容易阅读,我将代码分成两部分。之后,您可以轻松地将这两个部分合并为一个函数。

首先,使用递归获取所有名称矩阵的函数:

anames <- function(x) {

   require(plyr)
   if (is.data.frame(x)) return(NA)

   y <- do.call(rbind.fill.matrix,
                mapply(cbind, names(x), lapply(x, anames),
                       SIMPLIFY = FALSE))
   colnames(y) <- NULL

   return(y)
}

anames(a)
#      [,1] [,2] [,3] [,4]
# [1,] "b1" "c1" "d1" NA  
# [2,] "b1" "c2" NA   NA  
# [3,] "b2" NA   NA   NA

然后,一个函数应用给定的steps 输入,并按照您的要求填充NAs:

listToMatrix <- function(myList, steps = Inf) {

   a <- anames(myList)
   steps <- min(steps, ncol(a) - 1)
   cols.idx <- seq_len(steps)
   a <- a[, cols.idx]
   for (j in tail(cols.idx, -1))
      a[, j] <- ifelse(is.na(a[, j]), a[, j - 1], a[, j])

   return(a)
}

listToMatrix(a, 2)
#      [,1] [,2]
# [1,] "b1" "c1"
# [2,] "b1" "c2"
# [3,] "b2" "b2"

【讨论】:

  • 哇,谢谢!它完全按照我的意愿工作 :) 非常感谢!
猜你喜欢
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2022-10-07
  • 2017-02-18
  • 1970-01-01
相关资源
最近更新 更多