如何在 R 中将矩阵分成更小的矩阵?

问题描述 投票:0回答:6

我有以下矩阵

2    4    1
6    32   1
4    2    1
5    3    2
4    2    2

我想根据第三列制作以下两个矩阵

首先

2    4
6    32
4    2

第二

5    3
4    2

我能想到的最好的,但我得到一个错误

×<- cbind(mat[,1], mat[,2]) if mat[,3]=1

y<- cbind(mat[,1], mat[,2]) if mat[,3]=2

r matrix
6个回答
17
投票

如果

mat
是你的矩阵:

mat <- matrix(1:15,ncol=3)
mat[,3] <- c(1,1,1,2,2)
> mat
     [,1] [,2] [,3]
[1,]    1    6    1
[2,]    2    7    1
[3,]    3    8    1
[4,]    4    9    2
[5,]    5   10    2

然后你就可以使用

split
:

> lapply( split( mat[,1:2], mat[,3] ), matrix, ncol=2)
$`1`
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8

$`2`
     [,1] [,2]
[1,]    4    9
[2,]    5   10

lapply
中的
matrix
是必要的,因为 split 会删除使向量成为矩阵的属性,因此您需要将它们添加回来。


7
投票

另一个例子:

#test data
mat <- matrix(1:15,ncol=3)
mat[,3] <- c(1,1,1,2,2)

#make a list storing a matrix for each id as components
result <- lapply(by(mat,mat[,3],identity),as.matrix)

最终产品:

> result
$`1`
  V1 V2 V3
1  1  6  1
2  2  7  1
3  3  8  1

$`2`
  V1 V2 V3
4  4  9  2
5  5 10  2

4
投票

如果你有一个矩阵 A,当第三列为 1 时,这将获得前两列:

A[A[,3] == 1,c(1,2)]

您可以使用它来获取第三列中任何值的矩阵。

解释:A[,3] == 1 返回一个布尔向量,其中如果 A[i,3] 为 1,则第 i 个位置为 TRUE。该布尔向量可用于索引到矩阵中以提取我们想要的行。

免责声明:我对 R 的经验很少,这是 MATLAB 式的方法。


4
投票

split.data.frame
也可用于分割
matrix

mat <- matrix(c(1:10,1,1,1,2,2), ncol=3)

x <- split.data.frame(mat[,-3], mat[,3])
x
#$`1`
#     [,1] [,2]
#[1,]    1    6
#[2,]    2    7
#[3,]    3    8
#
#$`2`
#     [,1] [,2]
#[1,]    4    9
#[2,]    5   10

str(x)
#List of 2
# $ 1: num [1:3, 1:2] 1 2 3 6 7 8
# $ 2: num [1:2, 1:2] 4 5 9 10

split
索引并在
lapply
中使用它来子集。

lapply(split(seq_along(mat[,3]), mat[,3]), \(i) mat[i, -3, drop=FALSE])
#$`1`
#     [,1] [,2]
#[1,]    1    6
#[2,]    2    7
#[3,]    3    8
#
#$`2`
#     [,1] [,2]
#[1,]    4    9
#[2,]    5   10

2
投票

这是 pedrosorio 想法的功能版本:

 getthird <- function(mat, idx) mat[mat[,3]==idx, 1:2]
 sapply(unique(mat[,3]), getthird, mat=mat)  #idx gets sent the unique values
#-----------
[[1]]
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8

[[2]]
     [,1] [,2]
[1,]    4    9
[2,]    5   10

0
投票

我们可以使用

by
tapply

> by(seq_along(mat[, 3]), mat[, 3], function(k) mat[k, -3])
mat[, 3]: 1
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
------------------------------------------------------------
mat[, 3]: 2
     [,1] [,2]
[1,]    4    9
[2,]    5   10

> tapply(seq_along(mat[, 3]), mat[, 3], function(k) mat[k, -3])
$`1`
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8

$`2`
     [,1] [,2]
[1,]    4    9
[2,]    5   10
© www.soinside.com 2019 - 2024. All rights reserved.