Alan20
Alan20

Reputation: 281

Changing elements in a matrix depending on their value

I asked a question yesterday about changing matrix values that can be found here:Changing values in a matrix depending on whether they are above of below a certain threshold value

I would like to do something slightly more complicated.

If an element of the matrix is less than or equal to 200, then I would like to multiply it by 4.

If an element of the matrix is greater than 200 and less than 400, then I would like to multiply it by 3.

If an element of the matrix is greater than or equal to 400, then I would like to change it's value to zero.

How to reproduce my matrix:

Matrix <- structure(c(122, 948, 952, 100,
        942, 150, 150, 149, 
        244, 220, 437, 395, 
        356, 473, 434, 335, 
        357, 371, 590, 553, 
        520, 491, 426, 426, 
        427, 177, 284, 338, 
        391, 290, 345, 399, 
        143, 193, 136, 121, 
        122, 187, 177, 544), .Dim = c(10L, 4L), units = structure(list(
          numerator = "m", denominator = character(0)), class = "symbolic_units"))

Upvotes: 0

Views: 75

Answers (4)

ThomasIsCoding
ThomasIsCoding

Reputation: 101508

Another base R option

Matrix*abs(Reduce("+",Map(function(x,y) y*(Matrix<=x),c(200,400),c(7,-3))))

which gives

> Matrix*abs(Reduce("+",Map(function(x,y) y*(Matrix<=x),c(200,400),c(7,-3))))
      [,1] [,2] [,3] [,4]
 [1,]  488    0    0 1035
 [2,]    0 1185    0 1197
 [3,]    0 1068    0  572
 [4,]  400    0    0  772
 [5,]    0    0    0  544
 [6,]  600 1005  708  484
 [7,]  600 1071  852  488
 [8,]  596 1113 1014  748
 [9,]  732    0 1173  708
[10,]  660    0  870    0
attr(,"units")
$numerator
[1] "m"

$denominator
character(0)

attr(,"class")
[1] "symbolic_units"

Upvotes: 0

Cath
Cath

Reputation: 24074

Another way to create your matrix of multiplication factors is to sum up the number of conditions (is it > 200 ? is it > 400) each element of your matrix fulfills and apply it to the vector of the 3 different multipliers:

Matrix * c(4, 3, 0)[(Matrix > 200) + (Matrix >= 400) + 1] # add + 1 to match positions in the 
                                                       # vector because result will be 0, 1 or 2

 #     [,1] [,2] [,3] [,4]
 #[1,]  488    0    0 1035
 #[2,]    0 1185    0 1197
 #[3,]    0 1068    0  572
 #[4,]  400    0    0  772
 #[5,]    0    0    0  544
 #[6,]  600 1005  708  484
 #[7,]  600 1071  852  488
 #[8,]  596 1113 1014  748
 #[9,]  732    0 1173  708
#[10,]  660    0  870    0
#attr(,"units")
#$numerator
#[1] "m"

#$denominator
#character(0)

#attr(,"class")
#[1] "symbolic_units"

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388982

Create a matrix of multiplication factors which is of same dimension as Matrix

ifelse(Matrix <= 200, 4, ifelse(Matrix < 400, 3, 0))

#      [,1] [,2] [,3] [,4]
# [1,]    4    0    0    3
# [2,]    0    3    0    3
# [3,]    0    3    0    4
# [4,]    4    0    0    4
# [5,]    0    0    0    4
# [6,]    4    3    4    4
# [7,]    4    3    3    4
# [8,]    4    3    3    4
# [9,]    3    0    3    4
#[10,]    3    0    3    0

You can then directly multiply it :

Matrix * ifelse(Matrix <= 200, 4, ifelse(Matrix < 400, 3, 0))


#      [,1] [,2] [,3] [,4]
# [1,]  488    0    0 1035
# [2,]    0 1185    0 1197
# [3,]    0 1068    0  572
# [4,]  400    0    0  772
# [5,]    0    0    0  544
# [6,]  600 1005  708  484
# [7,]  600 1071  852  488
# [8,]  596 1113 1014  748
# [9,]  732    0 1173  708
#[10,]  660    0  870    0
#attr(,"units")
#$numerator
#[1] "m"

#$denominator
#character(0)

#attr(,"class")
#[1] "symbolic_units"

Upvotes: 0

Yuriy Saraykin
Yuriy Saraykin

Reputation: 8880

You can use:

m <- Matrix
m * ((m <= 200) * 4  + (m > 200 & m < 400) * 3)

Upvotes: 2

Related Questions