矩阵到数据帧列表的列表

时间:2017-03-10 12:20:09

标签: r list matrix

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

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))

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

2 个答案:

答案 0 :(得分:3)

这种数据的特定结构可以通过称为递归索引的非常罕见的方法来访问。这三条线将产生结果。

# 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")]

答案 1 :(得分:1)

你可以做到

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

虽然&#39; subval&#39;变量似乎是多余的(它只能带一个 值)。在我看来,这更有意义

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