我想将列表层次结构(类似于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
,然后它应将先前的列表名称保留在矩阵中。有什么建议么? :)
最佳答案
这是一个解决方案。因此,在这里阅读起来很容易,我将代码分为两部分。以后,您可以轻松地将两个部分合并为一个函数。
首先,使用递归获取所有名称矩阵的函数:
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
输入,并像您所要求的那样填充NA
: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"
关于R将列表层次结构展平为矩阵或data.frame,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12768114/