6

I have the following matrix

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

I want to make the following two matrices based on 3rd column

first

2    4
6    32
4    2

second

5    3
4    2

Best I can come up with, but I get an error

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

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

Community
  • 1
  • 1
Steve Hwang
  • 1,529
  • 4
  • 14
  • 11
  • 2
    Please post [reproducible examples](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) in the future. You'll get better responses that way. – Ari B. Friedman Oct 25 '12 at 00:49

4 Answers4

13

If mat is your matrix:

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

Then you can use 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

The lapply of matrix is necessary because split drops the attributes that make a vector a matrix, so you need to add them back in.

Ari B. Friedman
  • 69,285
  • 35
  • 174
  • 232
6

Yet another example:

#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)

Final product:

> 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
thelatemail
  • 85,757
  • 12
  • 122
  • 177
4

If you have a matrix A, this will get the first two columns when the third column is 1:

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

You can use this to obtain matrices for any value in the third column.

Explanation: A[,3] == 1 returns a vector of booleans, where the i-th position is TRUE if A[i,3] is 1. This vector of booleans can be used to index into a matrix to extract the rows we want.

Disclaimer: I have very little experience with R, this is the MATLAB-ish way to do it.

pedrosorio
  • 850
  • 4
  • 7
1

This is a functional version of pedrosorio's idea:

 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
IRTFM
  • 251,731
  • 20
  • 347
  • 472