我有以下矩阵
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
如果
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 会删除使向量成为矩阵的属性,因此您需要将它们添加回来。
另一个例子:
#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
如果你有一个矩阵 A,当第三列为 1 时,这将获得前两列:
A[A[,3] == 1,c(1,2)]
您可以使用它来获取第三列中任何值的矩阵。
解释:A[,3] == 1 返回一个布尔向量,其中如果 A[i,3] 为 1,则第 i 个位置为 TRUE。该布尔向量可用于索引到矩阵中以提取我们想要的行。
免责声明:我对 R 的经验很少,这是 MATLAB 式的方法。
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
这是 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
我们可以使用
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