为什么rbind和cbind用sapply产生相同的输出

rns*_*nso 1 r apply

以下列表列表:

> lll = list(list(5,3,4), list(5,3,7), list(6,2,1), list(6,1,3), list(5,2,1))
Run Code Online (Sandbox Code Playgroud)

我期望输出与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
Run Code Online (Sandbox Code Playgroud)

为什么会这样,什么代码会产生cbind vs rbind的转置输出?

Tim*_*man 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   
Run Code Online (Sandbox Code Playgroud)

它相当于:

> sapply(list(rbind(list(1,2,3)),rbind(list(4,5,6))),identity)
Run Code Online (Sandbox Code Playgroud)

这相当于:

> sapply(list(matrix(list(1,2,3),c(1,3)),matrix(list(4,5,6),c(1,3))),identity)
Run Code Online (Sandbox Code Playgroud)

这相当于这个,因为sapply关心它们的长度,而不是它们的尺寸:

> sapply(list(c(1,2,3),c(4,5,6)),identity)
Run Code Online (Sandbox Code Playgroud)

这基本上就是这个(因为sapply它们组合成列):

> cbind(c(1,2,3),c(4,5,6))
Run Code Online (Sandbox Code Playgroud)

你真正想要的是调用rbind一次,每个子列表作为参数,而不是在每个子列表上单独调用它.换句话说,你希望它像这样工作:

> rbind(list(1,2,3),list(4,5,6))
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
Run Code Online (Sandbox Code Playgroud)

但是,由于您已将子列表存储在单个列表中,因此可以通过使用来实现此目的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   
Run Code Online (Sandbox Code Playgroud)