如何在R中从向量列表创建一个矩阵?

116
目标:从一个等长的向量列表中创建一个矩阵,其中每个向量都成为一行。
示例:
> a <- list()
> for (i in 1:10) a[[i]] <- c(i,1:5)
> a
[[1]]
[1] 1 1 2 3 4 5

[[2]]
[1] 2 1 2 3 4 5

[[3]]
[1] 3 1 2 3 4 5

[[4]]
[1] 4 1 2 3 4 5

[[5]]
[1] 5 1 2 3 4 5

[[6]]
[1] 6 1 2 3 4 5

[[7]]
[1] 7 1 2 3 4 5

[[8]]
[1] 8 1 2 3 4 5

[[9]]
[1] 9 1 2 3 4 5

[[10]]
[1] 10  1  2  3  4  5
我想要:
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5 
6个回答

139

一种选项是使用do.call()

 > do.call(rbind, a)
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5

5
这和标准的rbind()之间的区别在于,do.call()将每个列表项作为单独的参数传递 - 这是正确的吗?do.call(rbind, a)相当于rbind(a[[1]], a[[2]],... a[[10]])? - Matt Parker
5
do.call()非常适合这个目的,我希望它在介绍材料中有更好的"文档化"。 - andrewj

21

simplify2array 是一个基础函数,相当直观。然而,由于 R 的默认行为是首先按列填充数据,您需要转置输出结果。(sapply 使用 simplify2array,在 help(sapply) 中有记录。)

> t(simplify2array(a))
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5

17

内置的matrix函数有一个很好的选项byrow,可以使用它来输入数据。将这个选项与源列表上的unlist组合起来,可以得到一个矩阵。我们还需要指定行数,以便它可以将未列出的数据分解。即:

> matrix(unlist(a), byrow=TRUE, nrow=length(a) )
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5

或者按列填充矩阵,然后转置:t(matrix(unlist(a), ncol=length(a))) - Kalin

12

虽然不是很直接,但它可以工作:

> t(sapply(a, unlist))
      [,1] [,2] [,3] [,4] [,5] [,6]
 [1,]    1    1    2    3    4    5
 [2,]    2    1    2    3    4    5
 [3,]    3    1    2    3    4    5
 [4,]    4    1    2    3    4    5
 [5,]    5    1    2    3    4    5
 [6,]    6    1    2    3    4    5
 [7,]    7    1    2    3    4    5
 [8,]    8    1    2    3    4    5
 [9,]    9    1    2    3    4    5
[10,]   10    1    2    3    4    5

1
使用 rjson 的结果,colMeans 仅适用于此方法!谢谢! - mpyw

8
t(sapply(a, '[', 1:max(sapply(a, length))))

其中'a'是一个列表。 适用于行大小不相等的情况。


3
> library(plyr)
> as.matrix(ldply(a))
      V1 V2 V3 V4 V5 V6
 [1,]  1  1  2  3  4  5
 [2,]  2  1  2  3  4  5
 [3,]  3  1  2  3  4  5
 [4,]  4  1  2  3  4  5
 [5,]  5  1  2  3  4  5
 [6,]  6  1  2  3  4  5
 [7,]  7  1  2  3  4  5
 [8,]  8  1  2  3  4  5
 [9,]  9  1  2  3  4  5
[10,] 10  1  2  3  4  5

1
如果行的长度不相同,这种方法就行不通了,而do.call(rbind,...)仍然可以工作。 - rwst
有什么线索可以让它适用于行大小不相等且缺失行数据为NA的情况吗? - Arihant
1
@rwst 实际上,除非您真的打算在填充行末尾时重复使用向量,否则do.call(rbind,...)无法处理长度不相等的向量。请参阅Arihant的响应,以了解一种在末尾使用NA值填充的方法。 - Kalin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接