Tsvetoslav Ivanov
Tsvetoslav Ivanov

Reputation: 45

How to replace values in matrix based on true/false indices of another matrix?

I have been trying to replace all values below 0 with a 0 in this matrix:

vec.1 <- c(0, -1, -2, -1, 1, 0)
vec.2 <- c(-1, 0, -1.5, -2, 2, 1)
vec.3 <- c(-2, -1.5, 0, -1, 1, 2)
vec.4 <- c(-1, 0, -1, 0, 0, 1)
vec.5 <- c(1, 2, 1, 0, 0, -1)
vec.6 <- c(0, 1, 2, 1, -1, 0)

mat <- rbind(vec.1, vec.2, vec.3, vec.4, vec.5, vec.6, deparse.level = 0)

      [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0 -1.0 -2.0   -1    1    0
[2,]   -1  0.0 -1.5   -2    2    1
[3,]   -2 -1.5  0.0   -1    1    2
[4,]   -1  0.0 -1.0    0    0    1
[5,]    1  2.0  1.0    0    0   -1
[6,]    0  1.0  2.0    1   -1    0    

I tried this code:

for((i in mat[]) < 0) {i = 0}

But it does not work. I also tried:

matrix.positive <- mat < 0

      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] FALSE  TRUE  TRUE  TRUE FALSE FALSE
[2,]  TRUE FALSE  TRUE  TRUE FALSE FALSE
[3,]  TRUE  TRUE FALSE  TRUE FALSE FALSE
[4,]  TRUE FALSE  TRUE FALSE FALSE FALSE
[5,] FALSE FALSE FALSE FALSE FALSE  TRUE
[6,] FALSE FALSE FALSE FALSE  TRUE FALSE

mat[which(matrix.positive) = 0]

But it does not work either (I do realize this does not make much sense but I am new to R (and coding) so I attempt different approaches). Without the equal sign and the zero I get this vector:

 [1] -1.0 -2.0 -1.0 -1.0 -1.5 -2.0 -1.5 -1.0 -1.0 -2.0 -1.0 -1.0 -1.0

The solution must be very simple but I cannot work it out. I would be grateful if somebody can help me. Thanks!

Upvotes: 1

Views: 1329

Answers (2)

akrun
akrun

Reputation: 887078

We can either use replace with the logical matrix as the second parameter and replacement value as the third

replace(mat, mat < 0, 0)
#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    0    0    0    0    1    0
#[2,]    0    0    0    0    2    1
#[3,]    0    0    0    0    1    2
#[4,]    0    0    0    0    0    1
#[5,]    1    2    1    0    0    0
#[6,]    0    1    2    1    0    0

or use the assignment by extracting the values of the 'mat' based on the logical matrix and assigning it to 0

mat[mat < 0] <- 0

As it s a numeric matrix, arithmetic should also work

(mat >= 0) * mat

Upvotes: 3

G. Grothendieck
G. Grothendieck

Reputation: 269526

Try pmax:

pmax(mat, 0)

giving:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    0    0    0    1    0
[2,]    0    0    0    0    2    1
[3,]    0    0    0    0    1    2
[4,]    0    0    0    0    0    1
[5,]    1    2    1    0    0    0
[6,]    0    1    2    1    0    0

Upvotes: 3

Related Questions