我想从矩阵列表中创建交错矩阵。
示例输入:
> l <- list(a=matrix(1:4,2),b=matrix(5:8,2))
> l
$a
[,1] [,2]
[1,] 1 3
[2,] 2 4
$b
[,1] [,2]
[1,] 5 7
[2,] 6 8
预期产出:
1 3
5 7
2 4
6 8
我已经检查了gdata中的interleave函数,但它没有显示列表的这种行为。任何帮助表示赞赏。
答案 0 :(得分:5)
这是一个单行:
do.call(rbind, l)[order(sequence(sapply(l, nrow))), ]
# [,1] [,2]
# [1,] 1 3
# [2,] 5 7
# [3,] 2 4
# [4,] 6 8
为了帮助理解,首先使用do.call(rbind, l)
将矩阵堆叠在一起,然后按正确的顺序提取行:
sequence(sapply(l, nrow))
# a1 a2 b1 b2
# 1 2 1 2
order(sequence(sapply(l, nrow)))
# [1] 1 3 2 4
它可以处理任意数量的矩阵,即使它们没有相同的行数,它也会做“正确的”(主观的)。
答案 1 :(得分:4)
您可以修改它以使您到达目的地,而不是重新发明轮子。
“gdata”中的interleave
函数以...
开头,可让您指定要放在一起的data.frame
个或矩阵的数量。函数的前几行看起来像这样:
head(interleave)
#
# 1 function (..., append.source = TRUE, sep = ": ", drop = FALSE)
# 2 {
# 3 sources <- list(...)
# 4 sources[sapply(sources, is.null)] <- NULL
# 5 sources <- lapply(sources, function(x) if (is.matrix(x) ||
# 6 is.data.frame(x))
您只需重写第1行和第3行as I did in this Gist即可创建list
版interleave
(此处,我称之为Interleave
)
head(Interleave)
#
# 1 function (myList, append.source = TRUE, sep = ": ", drop = FALSE)
# 2 {
# 3 sources <- myList
# 4 sources[sapply(sources, is.null)] <- NULL
# 5 sources <- lapply(sources, function(x) if (is.matrix(x) ||
# 6 is.data.frame(x))
有效吗?
l <- list(a=matrix(1:4,2),b=matrix(5:8,2), c=matrix(9:12,2))
Interleave(l)
# [,1] [,2]
# a 1 3
# b 5 7
# c 9 11
# a 2 4
# b 6 8
# c 10 12