Skip to content

efficient way to replace a range of numeric with a integer in a matrix

5 messages · Richard M. Heiberger, William Dunlap, Jinsong Zhao +1 more

#
Hi there,

I hope to replace a range of numeric in a matrix with a integer. For 
example, in the following matrix, I want to use 1 to replace the 
elements range from 0.0 to 1.0, and all larger than 1. with 2.

 > (m <- matrix(runif(16, 0, 2), nrow = 4))
           [,1]       [,2]      [,3]     [,4]
[1,] 0.7115088 0.55370418 0.1586146 1.882931
[2,] 0.9068198 0.38081423 0.9172629 1.713592
[3,] 1.5210150 0.93900649 1.2609942 1.744456
[4,] 0.3779058 0.03130103 0.1893477 1.601181

so I want to get something like:

      [,1] [,2] [,3] [,4]
[1,]    1    1    1    2
[2,]    1    1    1    2
[3,]    2    1    2    2
[4,]    1    1    1    2

I wrote a function to do such thing:

fun <- function(x) {
     if (is.na(x)) {
         NA
     } else if (x > 0.0 && x <= 1.0) {
         1
     } else if (x > 1.0) {
         2
     } else {
         x
     }
}

Then run it as:

 > apply(m,2,function(i) sapply(i, fun))

However, it seems that this method is not efficient when the dimension 
is large, e.g., 5000x5000 matrix.

Any suggestions? Thanks in advance!

Best regards,
Jinsong
#
(m>1)+1
On Mon, Aug 11, 2014 at 5:40 PM, Jinsong Zhao <jszhao at yeah.net> wrote:
#
You can use
    m[m > 0 & m <= 1.0] <- 1
    m[m > 1 ] <- 2
or, if you have lots of intervals, something based on findInterval().  E.g.,
    m[] <- findInterval(m, c(-Inf, 0, 1, Inf)) - 1

(What do you want to do with non-positive numbers?)

Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Mon, Aug 11, 2014 at 2:40 PM, Jinsong Zhao <jszhao at yeah.net> wrote:
#
On 2014/8/11 14:50, William Dunlap wrote:
Thank you very much.

I think findInterval() is what I want.

Regards,
Jinsong
#
On Aug 11, 2014, at 3:27 PM, Jinsong Zhao wrote:

            
OR, if you have irregularly spaced intervals or particular values to match to the intervals,  you can use findInterval to define categories and select with "[":
[,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
 [1,] 16.85 16.52  8.47 12.28 11.03 11.61  8.16  4.78 17.56 16.96
 [2,]  7.18 21.43  1.09 13.52  8.19  6.08 10.93  9.55 11.29  7.62
 [3,] 11.82  3.06  9.14 15.18 13.79 17.88 12.91 13.12 10.44 13.25
 [4,] 13.16  8.61 16.07  6.96  6.37 13.21 17.00  5.23  9.40 16.96
 [5,] 12.02  9.33 19.48 12.52  3.16 10.45  6.36  7.29  4.03  4.45
 [6,]  9.47 13.18  7.85  1.41 12.16 11.38 16.51 12.90 13.06  5.70
 [7,] 17.56  8.58  8.71  6.08  5.94 13.40 11.68 13.84  8.91  4.34
 [8,]  9.53 -3.28  1.18  5.75 17.22 10.45 15.19 12.32  9.09  2.70
 [9,] 20.09 -2.20 12.30 -2.07  7.84 -4.97 14.60  5.57 14.67 10.40
[10,]  9.69 16.60  6.80 10.18 13.28 11.42 13.60  4.50 14.11 13.27
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   16   16    4    8    8    8    4    2   16    16
 [2,]    4   32    1    8    4    4    8    4    8     4
 [3,]    8    2    4   16    8   16    8    8    8     8
 [4,]    8    4   16    4    4    8   16    4    4    16
 [5,]    8    4   32    8    2    8    4    4    2     2
 [6,]    4    8    4    1    8    8   16    8    8     4
 [7,]   16    4    4    4    4    8    8    8    4     2
 [8,]    4    1    1    4   16    8   16    8    4     2
 [9,]   32    1    8    1    4    1    8    4    8     8
[10,]    4   16    4    8    8    8    8    2    8     8