0
votes

I have 2 matrices

  1. matrix1 (nrow=3, ncol=3)
  2. matrix2 (nrow=5, ncol=5)

I know how to compare and replace conditionnaly an element of a matrix by an element of another matrix, but ONLY if these 2 elements are sharing the same [i,j] like this :

ifelse(matrix1<0.5, matrix2[,], matrix1[,])

Question:

Here I'd like to replace an element of matrix1, by an element of matrix2 of another column like this:

If matrix1[i,j]<0.5 Then I want to replace it be matrix2[i,j+2] Else I want to replace it be matrix2[i,j+1]

The problem is:

  • I can't use loop because of performance
  • I don't know how to explain to ifelse to move on another column.

How can I do this kind of comparaison efficiently on big matrix ?

Here is the data:

> dput(matrix1)
structure(c(0.782534098718315, 0.279918688116595, 0.139927505282685, 
0.485497816000134, 0.150636059232056, 0.976677459431812, 0.101831247797236, 
0.491994257550687, 0.492571017006412), .Dim = c(3L, 3L))

> dput(matrix2)
structure(1:25, .Dim = c(5L, 5L))
1
Can you show the expected output as the j+3 may create Error subscript out of bounds.akrun
The number of columns in the second matrix is not consistent with what you want to do. But if is was, I would try first something like ifelse(a < 0.5, b[1:3,1:3+2], b[1:3,1:3+3])...Vincent Guillemot
I made a mistake it's j+1 instead of j+3.Ophelie
@Ophelie Could you show the expected output. It is confusing.akrun
You might try to manipulate the matrices accordingly so that you have a one-to-one match between elements in "matrix1" and "matrix2"; i.e. something like ifelse(matrix1 < 0.5, matrix2[seq_len(nrow(matrix1)), -c(1, 2)], matrix2[seq_len(nrow(matrix1)), -c(1, 5)]), although I'm not sure how generalisable this could be..alexis_laz

1 Answers

3
votes

Here m1 and m2 are the two matrices. Based on @alexis_laz comments, you could try

indx1 <- tail(seq(ncol(m1)+1),ncol(m1))
indx2 <-  tail(seq(ncol(m1)+2),ncol(m1))
rowInd <- 1:nrow(m1)
ifelse(m1 < 0.5, m2[rowInd,indx2], m2[rowInd, indx1])
#    [,1] [,2] [,3]
#[1,]    6   16   21
#[2,]   12   17   22
#[3,]   13   13   23

Or you can create index by

 indx <- cbind(c(row(m1)), c(col(m1)))
 indx1 <- cbind(indx[,1], indx[,2]+1)
 indx2 <- cbind(indx[,1], indx[,2]+2)
 ifelse(m1 < 0.5, m2[indx2], m2[indx1])
 #     [,1] [,2] [,3]
 #[1,]    6   16   21
 #[2,]   12   17   22
 #[3,]   13   13   23