【问题标题】:List of list of matrix to dataframe到数据框的矩阵列表列表
【发布时间】:2017-03-10 12:20:08
【问题描述】:

我有一个包含矩阵列表的列表,如下所示:

set.seed(123)

mat1 <- matrix(rnorm(9,1,2), ncol=3, nrow=3)
mat2 <- matrix(rnorm(9,1,3), ncol=3, nrow=3)

mynames <- c("a","b","c")

colnames(mat1) <- mynames
colnames(mat2) <- mynames

rownames(mat1) <- mynames
rownames(mat2) <- mynames

finallist <- list(val1 = list(subval1 = mat1), val2 = list(subval1 = mat2))

我希望得到如下输出:

goal <- data.frame(val1 = rnorm(9,1,2), val2 = rnorm(9,1,3), subval = rep("subval1",9), origrownames = rep(mynames, 3), origcolumnnames = rep(mynames,each=3))

我知道可能有一个可以使用 reshape 的中间数据框,但我似乎无法接近。我试过do.call("rbind", finallist),但这似乎并没有保留顶级列表和子列表的名称。此外,每个子列表包含 2000 个矩阵,每个矩阵的维度为 20x20,我计划使用此函数 20 多次,所以我正在寻找不太慢的东西。

【问题讨论】:

  • 您的 goal 数据框由 27 行组成,每个值包含 3 次。这是有意的还是您想要一个只有 9 行的 goal 数据框?
  • @gebi 啊,对不起。应该是origrownames = rep(mynames,3)

标签: r list matrix


【解决方案1】:

这种数据的特定结构可以通过一种相当罕见的方法访问,称为递归索引。这是将产生结果的三行代码。

# build row and column names variables
mydf <- data.frame(origrownames = rep(mynames, 3), origcolumnnames = rep(mynames, each=3))
# use matrix subsetting to extract val1 and val2 variables
mydf[c("val1", "val2")] <- list(finallist[[c(1,1)]][as.matrix(mydf)],
                                finallist[[2:1]][as.matrix(mydf)])
# extract subval1 from list
mydf$subval <- names(finallist$val1)

这里的兴趣点是第二行,它首先使用递归索引([[c(1, 1)]][[2:1]])来拉出嵌套列表中的元素,然后在矩阵的行和列名称上使用矩阵子集以所需的顺序提取值(有关这两种方法的详细信息,请参阅?"[")。

这些提取的输出被包装在一个列表中,然后馈送到mydf[c("va1", "val2")],后者将它们添加到具有所需名称的 data.frame 中。

返回

mydf
  origrownames origcolumnnames       val1       val2  subval
1            a               a -0.1209513 -0.3369859 subval1
2            b               a  0.5396450  4.6722454 subval1
3            c               a  4.1174166  2.0794415 subval1
4            a               b  1.1410168  2.2023144 subval1
5            b               b  1.2585755  1.3320481 subval1
6            c               b  4.4301300 -0.6675234 subval1
7            a               c  1.9218324  6.3607394 subval1
8            b               c -1.5301225  2.4935514 subval1
9            c               c -0.3737057 -4.8998515 subval1

您可以使用

对列重新排序
mydf <- mydf[c("val1", "val2", "subval", "origrownames", "origcolumnnames")]

【讨论】:

  • 谢谢,我了解了递归索引。我还发现从data.table 应用melt 可以直接做到这一点。
【解决方案2】:

你可以的

tmp <- simplify2array(unlist(finallist, FALSE))
setNames(cbind(expand.grid(dimnames(tmp)[-3]), apply(tmp, 3, c), 'subval1'),
         c('origrownames', 'origcolumnames', names(finallist), 'subval'))
#  origrownames origcolumnames       val1       val2  subval
#1            a              a -0.1209513 -0.3369859 subval1
#2            b              a  0.5396450  4.6722454 subval1
#3            c              a  4.1174166  2.0794415 subval1
#4            a              b  1.1410168  2.2023144 subval1
#5            b              b  1.2585755  1.3320481 subval1
#6            c              b  4.4301300 -0.6675234 subval1
#7            a              c  1.9218324  6.3607394 subval1
#8            b              c -1.5301225  2.4935514 subval1
#9            c              c -0.3737057 -4.8998515 subval1

虽然 'subval' 变量看起来是多余的(它只能取一个 价值)。在我看来,这更有意义

setNames(as.data.frame.table(simplify2array(lapply(finallist, '[[', 1))),
         c('origrownames', 'origcolumnames', 'variable', 'value'))
#   origrownames origcolumnames variable      value
#1             a              a     val1 -0.1209513
#2             b              a     val1  0.5396450
#3             c              a     val1  4.1174166
#4             a              b     val1  1.1410168
#5             b              b     val1  1.2585755
#6             c              b     val1  4.4301300
#7             a              c     val1  1.9218324
#8             b              c     val1 -1.5301225
#9             c              c     val1 -0.3737057
#10            a              a     val2 -0.3369859
#11            b              a     val2  4.6722454
#12            c              a     val2  2.0794415
#13            a              b     val2  2.2023144
#14            b              b     val2  1.3320481
#15            c              b     val2 -0.6675234
#16            a              c     val2  6.3607394
#17            b              c     val2  2.4935514
#18            c              c     val2 -4.8998515

【讨论】:

    猜你喜欢
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    相关资源
    最近更新 更多