以下列表:
> lll = list(list(5,3,4), list(5,3,7), list(6,2,1), list(6,1,3), list(5,2,1))
我希望输出与rbind和cbind一起转换为sapply,但它们是相同的:
> sapply(lll, rbind)
[,1] [,2] [,3] [,4] [,5]
[1,] 5 5 6 6 5
[2,] 3 3 2 1 2
[3,] 4 7 1 3 1
> sapply(lll, cbind)
[,1] [,2] [,3] [,4] [,5]
[1,] 5 5 6 6 5
[2,] 3 3 2 1 2
[3,] 4 7 1 3 1
>
> identical(sapply(lll, cbind), sapply(lll, rbind))
[1] TRUE
为什么会这样,哪些代码会生成cbind vs rbind的转置输出?
答案 0 :(得分:5)
您编写它的方式,rbind
将单独应用于您的每个子列表,因此它实际上并没有将它们与任何内容组合。在这种情况下,它真正做的就是将维度属性添加到子列表,将其从包含length=3
的列表更改为具有dim=c(1,3)
的矩阵。 cbind
会做同样的事情,除非你得到dim=c(3,1)
。关键是,正如您所写的那样,rbind
和cbind
实际上并不用于将子列表组合在一起。这完全由sapply
完成,而sapply
并不关心它们作为矩阵的维度。它将它们视为向量并将它们组合为列。
考虑这个稍微简单的例子:
> sapply(list(list(1,2,3),list(4,5,6)),rbind)
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
它等同于:
> sapply(list(rbind(list(1,2,3)),rbind(list(4,5,6))),identity)
相当于:
> sapply(list(matrix(list(1,2,3),c(1,3)),matrix(list(4,5,6),c(1,3))),identity)
这相当于此,因为sapply
关心它们的长度而不是它们的尺寸:
> sapply(list(c(1,2,3),c(4,5,6)),identity)
基本上就是这个(因为sapply
将它们组合成列):
> cbind(c(1,2,3),c(4,5,6))
你真正想要的是调用rbind
一次,每个子列表作为参数,而不是在每个子列表上单独调用它。换句话说,你希望它像这样工作:
> rbind(list(1,2,3),list(4,5,6))
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
但是,由于您已将子列表存储在单个列表中,因此可以使用do.call
来实现此目的,这样您就可以将rbind
的所有参数作为单个list
提供:
> list_of_lists <- list(list(1,2,3),list(4,5,6))
> do.call(rbind, list_of_lists)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
答案 1 :(得分:1)
要获得所需的输出,您可以尝试使用do.call
和lapply
:
rbind
:
do.call(rbind, lapply(lll, rbind))
cbind
:
do.call(cbind, lapply(lll, cbind))
正如@ zx8754所指出的那样,实际上可以跳过apply
的使用并只使用do.call
来完成它(对于列表中的列表我不知道的事情)谢谢!):
cbind
和rbind
:
do.call(cbind, lll)
do.call(rbind, lll)
谢谢!
答案 2 :(得分:1)
通常,cbind
和rbind
适用于矢量。例如,请看:
v <- c(3,1,2)
cbind(v)
# v
#[1,] 3
#[2,] 1
#[3,] 2
rbind(v)
# [,1] [,2] [,3]
#v 3 1 2
但sapply
有一个名为simplify
的参数,默认情况下为TRUE
,此参数会中和代码中rbind
和cbind
的效果。参数?sapply
的{{1}}表示:
逻辑或字符串;如果可能,结果是否应简化为矢量,矩阵或更高维数?
实际上你的代码所做的与这段代码相同:
simplify
为了使其有效,我做了(尽管其他人已经建议):
sapply(lll, function(x) x)
或使用x <- do.call(rbind, lll)
# [,1] [,2] [,3]
# [1,] 5 3 4
# [2,] 5 3 7
# [3,] 6 2 1
# [4,] 6 1 3
# [5,] 5 2 1
t(x)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 5 5 6 6 5
# [2,] 3 3 2 1 2
# [3,] 4 7 1 3 1
库:
data.table
或者
x <- rbindlist(lll)
t(x)
一旦我们得到一个表单的输出(例如x <- matrix(unlist(lll), ncol = 3, byrow = T)
t(x)
),我们将结果转置为另一个表单(为rbind
情况完成)。