矩阵列表清单

时间:2017-04-15 11:08:13

标签: r list matrix

我有一个列表列表,我想将其转换为矩阵,以便每列=一个子列表。

模拟示例

list1 <- list(1, 2)
list2 <- list(1, 2, 3)
list3 <- list(1, 2, 3, 4)

list_lists <- list (list1, list2, list3)

我首先将所有子列表的长度逐渐增加(如果需要,使用NULL填充),以便所有子列表都具有最长的子列表。这是为了避免让R重复数据来填充最终矩阵中的行(如果我能以某种方式跳过此步骤,请随意)。

max_length <- max(unlist(lapply (list_lists, FUN = length)))
list_lists <- lapply (list_lists, function (x) {length (x) <- max_length; return (x)})

到目前为止我的最佳尝试

mat <- lapply (list_lists, cbind)

mat看起来非常像我想要的但实际上并非如此。它不是一个矩阵(尝试使用as.matrix将其转换为一个矩阵是不成功的)并且我不能像使用矩阵那样引用列/行。

我期待

     [,1] [,2] [,3]
[1,] 1    1    1   
[2,] 2    2    2   
[3,] NULL 3    3   
[4,] NULL NULL 4   

对我来说奇怪的是

mat <- cbind (list_lists[[1]], list_lists[[2]], list_lists[[3]])

似乎有效。我敢打赌这两行是一样的,它们怎么可能不同呢?

3 个答案:

答案 0 :(得分:5)

它们不同, lapply 会返回一个列表,请参阅下面的文档摘录

使用do.call代替mat <- lapply (list_lists, cbind),如下所示:

mat <- do.call("cbind",list_lists)

do.callcbind (list_lists[[1]], list_lists[[2]], list_lists[[3]])相同,它恰好在一系列列表上运行,这些列表将是数据帧列。

> do.call("cbind",list_lists)
     [,1] [,2] [,3]
[1,] 1    1    1   
[2,] 2    2    2   
[3,] NULL 3    3   
[4,] NULL NULL 4   
> 

了解do.call:

来自文档:

  

do.call 构造并执行来自名称或的函数调用   函数和要传递给它的参数列表。

     

lapply 返回与X相同长度的列表,每个元素都包含在内   是将FUN应用于X的相应元素的结果。

在r控制台上搜索?do.call?lapply

您还可以阅读:do.calllapply

答案 1 :(得分:2)

使用sapply而不是像这样的lappy:

list_lists <- sapply (list_lists, function (x) {length (x) <- max_length; return (x)})

这应该给你你想要的矩阵。似乎sapply将以递归方式取消列出list_lists中的每个列表,然后应用您指定的函数并将所有输出包装到矩阵中,有效地绕过您在上面指定的另一行。

答案 2 :(得分:1)

stri_list2matrix函数应该能够解决这个问题:

library(stringi)
stri_list2matrix(list_lists)
##      [,1] [,2] [,3]
## [1,] "1"  "1"  "1" 
## [2,] "2"  "2"  "2" 
## [3,] NA   "3"  "3" 
## [4,] NA   NA   "4" 

另一种选择是使用你的&#34; max_length&#34;创建矩阵:

ml <- max(lengths(list_lists))
do.call(cbind, lapply(list_lists, function(x) `length<-`(unlist(x), ml)))
##      [,1] [,2] [,3]
## [1,]    1    1    1
## [2,]    2    2    2
## [3,]   NA    3    3
## [4,]   NA   NA    4

第三种选择是使用来自&#34; reshape2&#34;的melt

library(reshape2)
dcast(melt(list_lists), L2 ~ L1)
##   L2  1  2 3
## 1  1  1  1 1
## 2  2  2  2 2
## 3  3 NA  3 3
## 4  4 NA NA 4